Search

Clear filter
Announcement
Anastasia Dyubaylo · Aug 3, 2021

InterSystems IRIS Analytics Contest

Hey Developers, Welcome to the next InterSystems online programming competition: 🏆 InterSystems IRIS Analytics Contest 🏆 Duration: August 23 - September 12, 2021 Total prize: $8,750 Landing page: https://contest.intersystems.com Prizes 1. Experts Nomination - a specially selected jury will determine winners: 🥇 1st place - $4,000 🥈 2nd place - $2,000 🥉 3rd place - $1,000 2. Community winners - applications that will receive the most votes in total: 🥇 1st place - $1,000 🥈 2nd place - $500 🥉 3rd place - $250 If several participants score the same amount of votes, they all are considered winners, and the money prize is shared among the winners. Who can participate? Any Developer Community member, except for InterSystems employees (ISC contractors allowed). Create an account! 👥 Developers can team up to create a collaborative application. Allowed from 2 to 5 developers in one team. Do not forget to highlight your team members in the README of your application – DC user profiles. Contest Period 🛠 August 23 - September 5: Application development and registration phase. ✅ September 6 - 12: Voting period. Note: Developers can improve their apps throughout the entire registration and voting period. The topic 💡 Analytics solutions using InterSystems IRIS 💡 Use one or more InterSystems IRIS analytics capabilities such as: Adaptive Analytics (AtScale) InterSystems Reports (Logi) InterSystems BI (DeepSee) InterSystems NLP (iKnow) to create a simple compelling, and clear visualization and/or story. Here are the requirements: Accepted applications: new to Open Exchange apps or existing ones, but with a significant improvement. Our team will review all applications before approving them for the contest. The application should work either on IRIS Community Edition or IRIS for Health Community Edition (except Adaptive Analytics and InterSystems Reports). The application should be Open Source and published on GitHub. The README file to the application should be in English, contain the installation steps, and contain either the video demo or/and a description of how the application works. Helpful resources 1. Sample applications and instructions: 1.1. Adaptive Analytics: Adaptive Analytics in Action (video) 1.2 InterSystems Reports: A look at InterSystems Reports (video) InterSystems Reports Resource guide Running InterSystems Reports in containers IRIS reports server demo (OEX) 1.3 IRIS BI examples: IRIS Analytics Template Samples BI Covid19 analytics Analyze This Game of Throne Analytics Pivot Subscriptions Error Globals Analytics Creating InterSystems IRIS BI Solutions Using Docker & VSCode (video) The Freedom of Visualization Choice: InterSystems BI (video) InterSystems BI(DeepSee) Overview (online course) InterSystems BI(DeepSee) Analyzer Basics (online course) 1.4 InterSystems NLP (iKnow): iKnow Source Code Samples Aviation Set Analysis iKnow First Look (online course) 2. Sample data: Hole Foods database for IRIS BI (installed with SamplesBI package) Adventure Works, zip Synthea 3. Tools to import data into IRIS: CSVGEN and CSVGENUI S3 External Table 4. For beginners with IRIS Build a Server-Side Application with InterSystems IRIS Learning Path for beginners 5. How to submit your app to the contest: How to publish an application on Open Exchange How to submit an application for the contest Judgment Voting rules will be announced soon. Stay tuned! So! We're waiting for YOUR great project – join our coding marathon to win! ❗️ Please check out the Official Contest Terms here.❗️ Added an article on InterSystems Reports in containers and the related demo Added new section to helpful resources: ➡️ For beginners with IRIS Build a Server-Side Application with InterSystems IRIS Learning Path for beginners - thanks to @Yuri.Gomes for such a useful post! Thanks! Hey Developers, Watch the new video on InterSystems Developers YouTube: ⏯ Adaptive Analytics in InterSystems IRIS Hi Community, See a demonstration of InterSystems IRIS Adaptive Analytics and get a detailed description of this new offering for analytics end-users: ⏯ Demonstration: Adaptive Analytics in InterSystems IRIS Hey Developers, The start date of the Analytics contest has been postponed! Please welcome the new contest period: 🛠 August 23 - September 5: Application development and registration phase. ✅ September 6 - 12: Voting period. Stay tuned! Hi Community! The registration period will be soon! We are waiting for your awesome solutions! Hey Community! Only 4 days left to the start of the registration period! You can use one or more InterSystems IRIS analytics capabilities such as: Adaptive Analytics (AtScale) InterSystems Reports (Logi) InterSystems BI (DeepSee) InterSystems NLP (iKnow) to create a simple compelling, and clear visualization and/or story. Hey DC members! Don't miss the upcoming InterSystems Analytics Contest Kick-off Webinar! Date & Time: Monday, August 23 — 10:00 AM EDT Speakers: 🗣 @Carmen Logue, InterSystems Product Manager - Analytics and AI🗣 @Evgeny Shvarov, InterSystems Developer Ecosystem Manager Developers! Tomorrow is starting the registration phase of InterSystems IRIS Analytics Contest! Don't forget about the upcoming InterSystems Analytics Contest Kick-off Webinar on Monday, August 23 — 10:00 AM EDT. We are waiting for you! Hi, Devs! The registration period has already begun! Please, upload your applications! We are waiting for your new and marvelous ideas!🤩 Hi Community! The recording of this webinar is available on InterSystems Developers YouTube! Please welcome: ⏯ InterSystems Analytics Contest Kick-Off Webinar Big applause to our speakers! 👏🏼 Dear Developers! Please use technology bonuses to collect more votes and get closer to victory. 🥳 Happy coding!✌ Hi Community! The registration period is continuing! Please, check out our Official Contest Terms here. Have a great day!😄 Developers! We are waiting for your great apps! Don't forget to participate! Dear developers! 🛠 The registration period ends on September 5th. Hurry up to upload your apps! Hey Developers! Today is the last day of the registration period! Upload your applications and solutions and take a part in the competition! Good luck to everybody!😉 Community! Registration time will end soon! And here 4 applications that are already in the competition: AlertDashboard by@Zhuang.Pan Analytics OKR by @Yuri.Gomes iris-analytics-datastudio by @Dmitry.Maslennikov promjet-stats by @Evgeniy.Potapov Who is gonna be next?
Announcement
Guillaume Rongier · Sep 1, 2021

French Stream On InterSystems Technologies

All French-speaking developers are friendly invited to follow a stream in the form of a journal. Every first Thursday of the month at 12:00 (Paris time), we organize a 30-45 minutes stream on Youtube with the following format : News on technologies around InterSystems. A section called "Did you know it?" (tips and tricks on IRIS) A "dossier", where we develop a subject (example: How language gateway works). And we end the program with an Interview of an french developer Previous episodes : Stream #0 : https://www.youtube.com/watch?v=ah0G7mNqa4E News 2020.4 in GA https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=HXIHRN_new20204 IAM deck https://docs.konghq.com/deck/ Le concours Outils InterSystems https://community.intersystems.com/post/intersystems-programming-contest-developer-tools Apps : https://community.intersystems.com/post/announcing-server-manager-20-visual-studio-code https://openexchange.intersystems.com/package/Config-API https://community.intersystems.com/post/environment-setup-config-api https://openexchange.intersystems.com/package/i2b2-on-iris-1 https://community.intersystems.com/post/containerising-netjava-gateways-or-kafka-integration-demo News https://community.intersystems.com/post/install-zpm-one-line https://community.intersystems.com/post/ssh-iris-container https://community.intersystems.com/post/intersystems-iris-multistage-builds Did you know it? Performance differences between methods/routines/labels https://gist.github.com/grongierisc/85dccbc573e2ad48cea2809ac80fc062 Dossier IAM Demo https://github.com/grongierisc/iam-training/tree/training Interview Lorenzo Scalese Stream #1 : https://www.youtube.com/watch?v=E87OYwO7w60 News https://community.intersystems.com/post/global-storage-everything-you-wanted-know-and-more https://community.intersystems.com/post/separate-list-results-persistent-classes-sql#comment-155671 https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCRN_new20204 New layout https://community.intersystems.com/post/pubsub-publish-subscribe-messages https://community.intersystems.com/post/introducing-intersystems-container-registry https://community.intersystems.com/post/mirroring-ensemble-service-information https://community.intersystems.com/post/should-we-store-external-files-intersystems-stream-or-windows-folders https://community.intersystems.com/post/intersystems-fhir-accelerator-programming-contest https://community.intersystems.com/post/new-video-embedded-python-intersystems-iris-sneak-peek https://community.intersystems.com/post/java-business-host-now-retired Did you know it? List vs Array Dossier PubSub https://github.com/grongierisc/iris-pubsub-cdc Interview Matthieu Laurent Stream #2 : https://www.youtube.com/watch?v=pszDXnzMi48 News https://community.intersystems.com/post/intersystems-iris-iris-health-healthshare-health-connect-20211-are-now-generally-available https://community.intersystems.com/post/ensemble-interoperability-training-course https://community.intersystems.com/post/looking-python-developers-iris-embedded-python-early-access-program Small Demo https://community.intersystems.com/post/intersystems-ai-contest-kick-webinar https://community.intersystems.com/post/lets-chat-join-intersystems-developers-discord https://community.intersystems.com/post/class-projections-and-projection-classes https://community.intersystems.com/post/how-verify-if-attribute-exists-object Did you know it? Persistence and SerialObject https://gist.github.com/grongierisc/629a4f966d103c19cc298b4bb833a6e Dossier External gateway https://github.com/grongierisc/iris-r-gateway-template Interview Fabien Cabot Stream #3 : https://www.youtube.com/watch?v=PrIQ9x6KdBM News https://community.intersystems.com/post/my-reviews-open-exchange-july-2021 https://spound.github.io/iris_offline_docs/ http://dreamymclean.intersystems.skytapdns.com:52773/csp/docbook/Doc.View.cls youtube links : fireship : https://www.youtube.com/c/Fireship micode : https://www.youtube.com/channel/UCYnvxJ-PKiGXo_tYXpWAC-w https://community.intersystems.com/contests/1 : https://community.intersystems.com/post/intersystems-iris-rest-application-patterns https://community.intersystems.com/post/add-business-item-your-production-code https://github.com/thewophile-beep/integrated-ml-demo Did you know it? Snapshot vs Resultset https://github.com/grongierisc/BatchSqlOutboundAdapter/tree/SnapShotvsResultSet SSR (Server Side Rendering) vs CSR (Client Side Rendering) Dossier How OBS works Interview Théophile Thierry Next : Stream #4 : https://www.youtube.com/watch?v=GHhowDrbmCc News https://community.intersystems.com/post/github-has-new-feature-vs-code-cloud https://blog.octo.com/ https://blog.octo.com/bd-le-deploiement-continu-cd/ https://www.developpez.com/ https://community.intersystems.com/contests/1 https://community.intersystems.com/post/intersystems-iris-analytics-contest https://openexchange.intersystems.com/package/Open-API-Client-Gen https://openexchange.intersystems.com/package/Export-Studio-Snippets-to-VS-Code https://www.docker.com/products/docker-desktop Did you know it? Parameter DEFAULTGLOBAL As STRING = "^IRIS.Temp.Rest.AsyncJob"; CORS with unantheticated user https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=GREST_cors#GREST_cors_configure Dossier Async REST Call https://github.com/grongierisc/iris-csvgen-ui/tree/master/src/Grongier/Rest/Async Interview Yann De Cambourg
Announcement
Anastasia Dyubaylo · Sep 29, 2021

InterSystems Interoperability Contest 2021

Hey Developers, Welcome to the next InterSystems online programming competition: 🏆 InterSystems Interoperability Contest 🏆 Duration: October 04-24, 2021 Our prize pool increased to $9,450! Prizes 1. Experts Nomination - a specially selected jury will determine winners: 🥇 1st place - $4,000 🥈 2nd place - $2,000 🥉 3rd place - $1,000 🌟 NEW PRIZES: 4-10th places - $100 2. Community winners - applications that will receive the most votes in total: 🥇 1st place - $1,000 🥈 2nd place - $500 🥉 3rd place - $250 If several participants score the same amount of votes, they all are considered winners, and the money prize is shared among the winners. Who can participate? Any Developer Community member, except for InterSystems employees (ISC contractors allowed). Create an account! 👥 Developers can team up to create a collaborative application. Allowed from 2 to 5 developers in one team. Do not forget to highlight your team members in the README of your application – DC user profiles. Contest Period 🛠 October 04-17: Application development and registration phase. ✅ October 18 - 24: Voting period. Note: Developers can improve their apps throughout the entire registration and voting period. The topic 💡 Interoperability solutions for InterSystems IRIS and IRIS for Health 💡 Develop an interoperability solution or a solution that helps to develop or/and maintain Interoperability solutions using InterSystems IRIS or InterSystems IRIS for Health. Requirements: Accepted applications: new to Open Exchange apps or existing ones, but with a significant improvement. Our team will review all applications before approving them for the contest. The application should work either on IRIS Community Edition or IRIS for Health Community Edition or IRIS Advanced Analytics Community Edition. The application should be Open Source and published on GitHub. The README file to the application should be in English, contain the installation steps, and contain either the video demo or/and a description of how the application works. Helpful resources 1. For beginners with InterSystems IRIS: Build a Server-Side Application with InterSystems IRIS Learning Path for beginners 2. Sample applications: Ensemble/Interoperability Formation IRIS-Interoperability-template ETL-Interoperability-Adapter InterSystems IRIS for Health ENSDEMO HL7 and SMS Interoperability Demo Twitter Sentiment Analysis with IRIS Healthcare HL7 XML RabbitMQ adapter PEX demo 3. Online courses & videos: Interoperability for Business Interoperability QuickStart Interoperability Resource Guide - 2019 Intelligent Interoperability Interoperability for Health Overview 4. How to submit your app to the contest: How to publish an application on Open Exchange How to submit an application for the contest Judgment Voting rules will be announced soon. Stay tuned! So! Ready. Set. Code. Please join our exciting coding marathon! ❗️ Please check out the Official Contest Terms here.❗️ Hey Devs! Don't miss the upcoming InterSystems Interoperability Contest Kick-off Webinar dedicated to the Interoperability Contest! Date & Time: Monday, October 4 — 12:00 AM EDT We are waiting for you, and good luck to everybody! Hey Community! We are waiting for your participation in the Interoperability Contest! Here is the landing page: https://contest.intersystems.com/ Dear Participants! Don't forget about technology bonuses to help you get closer to winning! 🎉 Please follow this post prepared by @Evgeny.Shvarov Happy coding!✌ Hey Developers, The recording of the Interoperability Contest Kick-off Webinar is available on InterSystems Developers YouTube! Please welcome: ⏯ InterSystems Interoperability Contest Kick-off Webinar Hi Community! The registration period is continuing! Please, check out our Official Contest Terms here. Have a great day!😄 Hello Developers! The first week of the registration period has ended, so only one week left! So, upload your applications and participate! For now, @Aleksandr.Kalinin6636 has added an application! It's called ESKLP, go check it out! Good luck to everybody, and easy coding! Developers! Hooray, we have another participant @Robert.Cemper1003 and his app CSV to M$-OFX. 🔥 Who will be next?👀 Developers! Today is the last day of the registration period! So, don't waste your time and upload your awesome applications! And here new participants to our contests, check out the apps: iris-crypto-tracker by @Evgeniy.Potapov LabResultsVerification-hl7 by @Muhammad.Waseem appmsw-telealerts by @MikhailenkoSergey
Announcement
Anastasia Dyubaylo · Mar 7, 2022

[Video] InterSystems Solutions in AWS

Hi Community, We'll look at moving InterSystems workload to the public cloud, then take a deep dive into the current architectures on the InterSystems cloud platform: ⏯ InterSystems Solutions in AWS Presenters:🗣 Jared Trog, Senior Cloud Engineer, InterSystems🗣 @Regilo.Souza, Product Owner - Cloud Strategy, InterSystems Enjoy watching and stay tuned!
Article
Iryna Mykhailova · Aug 2, 2022

Data models in InterSystems IRIS

Before we start talking about databases and different data models that exist, first we'd better talk about what a database is and how to use it. A database is an organized collection of data stored and accessed electronically. It is used to store and retrieve structured, semi-structured, or raw data which is often related to a theme or activity. At the heart of every database lies at least one model used to describe its data. And depending on the model it is based on, a database may have slightly different characteristics and store different types of data. To write, retrieve, modify, sort, transform or print the information from the database, a software called Database Management System (DBMS) is used. The size, capacity, and performance of databases and their respective DBMS have increased by several orders of magnitude. It has been made possible by technological advances in various areas, such as processors, computer memory, computer storage, and computer networks. In general, the development of database technology can be divided into four generations based on the data models or structure: navigational, relational, object and post-relational. Unlike the first three generations, which are characterized by a specific data model, the fourth generation includes many different databases based on different models. They include column, graph, document, component, multidimensional, key-value, in-memory etc. All these databases are united by a single name NoSQL (No SQL or now it is more accurate to say Not only SQL). Moreover, now a new class appears, which is called NewSQL. These are modern relational databases that aim to provide the same scalable performance as NoSQL systems for online transaction processing workloads (read-write) while using SQL and maintaining ACID. Incidentally, among these fourth generation databases are those that support multiple data models mentioned above. They are called multi-model databases. A good example of this type of database is InterSystems IRIS. That is why I will use it to give examples of different types of models as they appear. The first generation databases used hierarchical or network models. At the heart of the former is a tree structure where each record has only one owner. You can see how this works using the example of InterSystems IRIS, because its main model is hierarchical and all data is stored in globals (which are B*-trees). You can read more about globals here. We can create this tree in IRIS : Set ^a("+7926X", "city") = "Moscow" Set ^a("+7926X", "city", "street") = "Req Square" Set ^a("+7926X", "age") = 25 Set ^a("+7916Y", "city") = "London" Set ^a("+7916Y", "city", "street") = "Baker Street" Set ^a("+7916Y", "age") = 36 And see it in the database: After Edgar F. Codd proposed his relational algebra and his theory of data storage, using relational principles, in 1969. After, the relational databases were created. The use of relations (tables), attributes (columns), tuples (rows), and, most importantly, transactions and ACID requirements made these databases very popular and they remain so now. For example, we have the schema: We can create and populate tables: And if we write the query: select p.ID, p.Name, a.Country, A.City from My.Person p left join My.Address a on p.Address = a.ID we will receive the answer: Despite the significant advantages of relational databases, with the spread of object languages, it became necessary to store object-oriented data in databases. That's why in the 1990s the first object-oriented and object-relational databases appeared. The latter were created on the basis of relational databases by adding add-ons to simulate the work with objects. The former were developed from scratch based on the recommendations of the OMG (Object Management Group) consortium and after ODMG (Object Data Management Group). The key ideas of these object-oriented databases are the following. The single data warehouse is accessible using: object definition language - schema definition, allows defining classes, their attributes, relations, and methods, object-query language - declarative, almost SQL-like language that allows getting objects from the database, object manipulation language - allows modification and saving data in the database, supports transactions and method calls. This model allows obtaining data from databases using object-oriented languages. If we take the same structure as in the previous example but in the object-oriented form, we will have the following classes: Class My.Person Extends %Persistent { Property Name As %Name; Property Address As My.Address; } Class My.Address Extends %Persistent { Property Country; Property City; } And we can create the objects using the object-oriented language: set address = ##class(My.Address).%New() set address.Country = "France" set address.City = "Marseille" do address.%Save() set person = ##class(My.Person).%New() set person.Address = address set person.Name = "Quouinaut, Martin" do person.%Save() Unfortunately, object databases did not succeed in competing with relational databases from their dominant position, and as a result, many ORMs appeared. In any case, with the spread of the Internet in the 2000s and the emergence of new requirements for data storage, other data models and DBMSs started to emerge. Two of these models that are used in IRIS are document and column models. Document-oriented databases are used to manage semi-structured data. This is data that does not follow a fixed structure and carries the structure within it. Each unit of information in such a database is a simple pair: a key and a specific document. This document is formatted usually in JSON and contains the information. Since the database does not require a certain schema, it is also possible to integrate different types of documents in the same warehouse. If we take the previous example again, we can have documents like these: { "Name":"Quouinaut, Martin", "Address":{ "Country":"France", "City":"Paris" } } { "Name":"Merlingue, Luke", "Address":{ "Country":"France", "City":"Nancy" }, "Age":26 } These two documents with a different number of fields are stored in the IRIS database without any problem. And the last example of a model that will be available in version 2022.2 is the column model. In this case, the DBMS stores the data tables per column and not per row. Column orientation allows more efficient access to data for querying a subset of columns (eliminating the need to read columns that are not relevant), and more options for data compression. Compression by column is also more efficient when the data in the column is similar. However, they are generally less efficient for inserting new data. You can create this table: Create Table My.Address ( city varchar(50), zip varchar(5), country varchar(15) ) WITH STORAGETYPE = COLUMNAR In this case, the class is like this: Spoiler Class My.Address Extends %Persistent [ ClassType = persistent, DdlAllowed, Final, Owner = {UnknownUser}, ProcedureBlock, SqlRowIdPrivate, SqlTableName = Address ] { Property city As %Library.String(COLLATION = "EXACT", MAXLEN = 50) [ SqlColumnNumber = 2 ]; Property zip As %Library.String(COLLATION = "EXACT", MAXLEN = 5) [ SqlColumnNumber = 3 ]; Property country As %Library.String(COLLATION = "EXACT", MAXLEN = 15) [ SqlColumnNumber = 4 ]; Parameter STORAGEDEFAULT = "columnar"; Parameter USEEXTENTSET = 1; /// Bitmap Extent Index auto-generated by DDL CREATE TABLE statement. Do not edit the SqlName of this index. Index DDLBEIndex [ Extent, SqlName = "%%DDLBEIndex", Type = bitmap ]; Storage Default { <Data name="_CDM_city"> <Attribute>city</Attribute> <ColumnarGlobal>^q3AW.DZLd.1.V1</ColumnarGlobal> <Structure>vector</Structure> </Data> <Data name="_CDM_country"> <Attribute>country</Attribute> <ColumnarGlobal>^q3AW.DZLd.1.V2</ColumnarGlobal> <Structure>vector</Structure> </Data> <Data name="_CDM_zip"> <Attribute>zip</Attribute> <ColumnarGlobal>^q3AW.DZLd.1.V3</ColumnarGlobal> <Structure>vector</Structure> </Data> <DataLocation>^q3AW.DZLd.1</DataLocation> <ExtentLocation>^q3AW.DZLd</ExtentLocation> <ExtentSize>3</ExtentSize> <IdFunction>sequence</IdFunction> <IdLocation>^q3AW.DZLd.1</IdLocation> <Index name="DDLBEIndex"> <Location>^q3AW.DZLd.2</Location> </Index> <Index name="IDKEY"> <Location>^q3AW.DZLd.1</Location> </Index> <IndexLocation>^q3AW.DZLd.I</IndexLocation> <Property name="%%ID"> <AverageFieldSize>3</AverageFieldSize> <Selectivity>1</Selectivity> </Property> <Property name="city"> <AverageFieldSize>7</AverageFieldSize> <Selectivity>33.3333%</Selectivity> </Property> <Property name="country"> <AverageFieldSize>7</AverageFieldSize> <Selectivity>33.3333%</Selectivity> </Property> <Property name="zip"> <AverageFieldSize>7</AverageFieldSize> <Selectivity>33.3333%</Selectivity> </Property> <SQLMap name="%%DDLBEIndex"> <BlockCount>-4</BlockCount> </SQLMap> <SQLMap name="IDKEY"> <BlockCount>-4</BlockCount> </SQLMap> <SQLMap name="_CDM_city"> <BlockCount>-4</BlockCount> </SQLMap> <SQLMap name="_CDM_country"> <BlockCount>-4</BlockCount> </SQLMap> <SQLMap name="_CDM_zip"> <BlockCount>-4</BlockCount> </SQLMap> <StreamLocation>^q3AW.DZLd.S</StreamLocation> <Type>%Storage.Persistent</Type> } } Then we insert the data: insert into My.Address values ('London', '47000', 'UK') insert into My.Address values ('Paris', '54000', 'France') insert into My.Address values ('Kyiv', '03000', 'Ukraine') In the globals we see: If we open the global with the city names, we will see : And if we write a query: select City from My.Address we receive data: In this case, the DBMS just reads a global to get the whole result. And it saves time and resources when reading. So, we have talked about 5 different data models supported by the InterSystems IRIS database. These are the hierarchical, relational, object, document, and column models. Hope you will find this article useful when trying to figure out which models are available. If you have any questions feel free to ask them in the comments. Very nice article Excellent article - thank you very much for taking the time to write this up!!! 💡 This article is considered as InterSystems Data Platform Best Practice.
Announcement
Vadim Aniskin · Jan 18, 2023

InterSystems Ideas News #3

Hey Community! Welcome to the 3rd edition of the InterSystems Ideas news bulletin! Curious about what has happened on the Ideas Portal since the previous one? Read on! First of all, we've created a short video that explains the lifecycle of the ideas on the Portal: ⏯ Lifecycle of ideas on the InterSystems Ideas The most important piece of news is a brand new section on the portal - Portal Guide which contains: ✓ information about the Ideas Portal goal, ✓ a complete list of idea's statuses with their description, ✓ links related to the portal. Want to see something else there? Drop us a line in the comments! Another interesting tidbit is that 11 of your ideas are already in the status "Planned or in Progress". And, to complete this news bulletin, here is the list of the ideas that have already been implemented Career-oriented learning paths Change the layout of the "New idea" screen Enable the server widget on Discord Include support for gRPC protocol in IRIS Make JSON representation of messages in Interoperability message viewer instead of XML Create query builder Global->JSON->Global converter Chatbots solution for InterSystems Data Platforms 3DES support InterSystems IRIS as a Datasource for Google DataStudio Introduce a basic template to create interoperability adapters using Embedded Python Introduce the project of helpful one-liners As usual, don't forget to vote, comment, and subscribe to the ideas to track and influence their progress. We're looking forward to your ideas on the InterSystems Ideas portal!
Discussion
Olga Zavrazhnova · Aug 9, 2022

MEMErizible Technology - InterSystems Memes

A Minute Of Laughter on the Developer Community with #InterSystemsMemes Meme author: @Mathieu.Delagnes Have your own idea for a meme? Submit in this challenge on Global Masters. About InterSystems Memes rubric: A month ago we launched a challenge on Global Masters where we asked you to create memes about InterSystems technology. We had a lot of fun seeing all the entries so we decided to share this merriment with all DC members! 😁😁😁 Who's next?)) Don't hesitate to share the memes in the comments to this post as well ;) * ~90% under the surface For performance-minded folks: ...
Question
Ponnumani Gurusamy · Sep 20, 2016

InterSystems iKnow concepts

How to retrive the unstructure data using iknow concept in Cache . Given real time Example of these concepts? Here are some articles on community about that:Free Text Search by Kyle BaxteriKnow demo apps (1, 2, 3, 4) by Benjamin DeBoe I want to take a moment here and advise you to be very careful with iKnow. iKnow is NOT a solution, it is a way for you to develop your own solutions (much like Caché and Ensemble, actually). While iKnow can give structure to your free text fields, it cannot tell you what to do with that information once you gather it. So before implementing iKnow and developing a solution, you need to know what it is you want to look for, the purpose of putting the iKnow structure on your data, and what you are going to display or show off once you get it.
Article
Eduard Lebedyuk · Feb 5, 2016

Class Queries in InterSystems IRIS

Class Queries in InterSystems IRIS (and Cache, Ensemble, HealthShare) is a useful tool that separates SQL queries from Object Script code. Basically, it works like this: suppose that you want to use the same SQL query with different arguments in several different places.In this case you can avoid code duplication by declaring the query body as a class query and then calling this query by name. This approach is also convenient for custom queries, in which the task of obtaining the next row is defined by a developer. Sounds interesting? Then read on!Basic class queriesSimply put, basic class queries allow you to represent SQL SELECT queries. SQL optimizer and compiler handle them just as they would standard SQL queries, but they are more convenient when it comes to executing them from Caché Object Script context. They are declared as Query items in class definitions (similar to Method or Property) in the following way:Type: %SQLQueryAll arguments of your SQL query must be listed in the list of argumentsQuery type: SELECTUse the colon to access each argument (similar to static SQL)Define the ROWSPEC parameter which contains information about names and data types of the output results along with the order of fields(Optional) Define the CONTAINID parameter which corresponds to the numeric order if the field containing ID. If you don't need to return ID, don't assign any values to CONTAINID(Optional) Define the COMPILEMODE parameter which corresponds to the similar parameter in static SQL and specifies when the SQL expression must be compiled. When this parameter is set to IMMEDIATE (by default), the query will be compiled simultaneously with the class. When this parameter is set to DYNAMIC, the query will be compiled before its first execution (similar to dynamic SQL)(Optional) Define the SELECTMODE parameter which specifies the format of the query resultsAdd the SqlProc property, if you want to call this query as an SQL procedure.Set the SqlName property, if you want to rename the query. The default name of a query in SQL context is as follows: PackageName.ClassName_QueryNameCaché Studio provides the built-in wizard for creating class queriesSample definition of the Sample.Person class with the ByName query which returns all user names that begin with a specified letter Class Sample.Person Extends %Persistent { Property Name As %String; Property DOB As %Date; Property SSN As %String; Query ByName(name As %String = "") As %SQLQuery (ROWSPEC="ID:%Integer,Name:%String,DOB:%Date,SSN:%String", CONTAINID = 1, SELECTMODE = "RUNTIME", COMPILEMODE = "IMMEDIATE") [ SqlName = SP_Sample_By_Name, SqlProc ] { SELECT ID, Name, DOB, SSN FROM Sample.Person WHERE (Name %STARTSWITH :name) ORDER BY Name } } You can call this query from Caché Object Script in the following way: Set statement=##class(%SQL.Statement).%New() Set status=statement.%PrepareClassQuery("Sample.Person","ByName") If $$$ISERR(status) { Do $system.OBJ.DisplayError(status) } Set resultset=statement.%Execute("A") While resultset.%Next() { Write !, resultset.%Get("Name") } Alternatively, you can obtain a resultset using the automatically generated method queryNameFunc: Set resultset = ##class(Sample.Person).ByNameFunc("A") While resultset.%Next() { Write !, resultset.%Get("Name") } This query can also be called from SQLcontext in these two ways: Call Sample.SP_Sample_By_Name('A') Select * from Sample.SP_Sample_By_Name('A') This class can be found in the SAMPLES default Caché namespace And that's all about simple queries. Now let's proceed to custom ones. Custom class queries Though basic class queries work fine in most cases, sometimes it is necessary to execute full control over the query behavior in applications, e.g.: Sophisticated selection criteria. Since in custom queries you implement a Caché Object Script method that returns the next row on your own, these criteria can be as sophisticated as you require.If data is accessible only via API in a format that you don't want to useIf data is stored in globals (without classes)If you need to escalate rights in order to access dataIf you need to call an external API in order to access dataIf you need to gain access to the file system in order to access dataYou need to perform additional operations before running the query (e.g. establish a connection, check permissions, etc.) So, how do you create custom class queries? First of all, you should define 4 methods which implement the entire workflow for your query, from initialization to destruction: queryName — provides information about a query (similar to basic class queries)queryNameExecute — constructs a queryqueryNameFetch — obtains the next row result of a queryqueryNameClose — destructs a query Now let's analyze these methods in more detail. The queryName method The queryName method represents information about a query. Type: %QueryLeave body blankDefine the ROWSPEC parameter which contains the information about names and data types of the output results along with the field order(Optional) Define the CONTAINID parameter which corresponds to the numeric order if the field containing ID. If you don't return ID, don't assign any value to CONTAINID For example, let's create the AllRecords query (queryName = AllRecords, and the method is simply called AllRecords) which will be outputting all instances of the new persistent class Utils.CustomQuery, one by one. First, let's create a new persistent class Utils.CustomQuery: Class Utils.CustomQuery Extends (%Persistent, %Populate){ Property Prop1 As %String; Property Prop2 As %Integer; } Now let's write the AllRecords query: Query AllRecords() As %Query(CONTAINID = 1, ROWSPEC = "Id:%String,Prop1:%String,Prop2:%Integer") [ SqlName = AllRecords, SqlProc ] { } The queryNameExecute methodThe queryNameExecute method fully initializes a query. The signature of this method is as follows: ClassMethod queryNameExecute(ByRef qHandle As %Binary, args) As %Status where: qHandle is used for communication with other methods of the query implementationThis method must set qHandle into the state which will then be passed to the queryNameFetch methodqHandle can be set to OREF, variable or a multi-dimensional variableargs are additional parameters passed to the query. You can add as many args as you need (or don't use them at all)The method must return query initialization status But let's get back to our example. You are free to iterate through the extent in multiple ways (I will describe the basic working approaches for custom queries below), but as for this example let's iterate through the global using the $Order function. In this case, qHandle will be storing the current ID, and since we don't need any additional arguments, the arg argument is not required. The result looks like this: ClassMethod AllRecordsExecute(ByRef qHandle As %Binary) As %Status { Set qHandle = "" Quit $$$OK } The queryNameFetch methodThe queryNameFetch method returns a single result in $List form. The signature of this method is as follows: ClassMethod queryNameFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = queryNameExecute ] where: qHandle is used for communication with other methods of the query implementationWhen the query is executed, qHandle is being assigned values specified by queryNameExecute or by previous call of queryNameFetch.Row will be set either to a value of %List or to an empty string, if all data has been processedAtEnd must be set to 1, once the end of data is reached.The PlaceAfter keyword identifies the method's position in the int code . The "Fetch" method must be positioned after the "Execute" method, but this is important only for static SQL, i.e. cursors inside queries. In general, the following operations are performed within this method: Check whether we've reached the end of dataIf there is still some data left: Create a new %List and assign a value to the Row variableOtherwise, set AtEnd to 1Prepare qHandle for the next result fetchReturn the status This is how it will look like in our example: ClassMethod AllRecordsFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status { #; Iterating through ^Utils.CustomQueryD #; Writing the next id to qHandle and writing the global's value with the new id into val Set qHandle = $Order(^Utils.CustomQueryD(qHandle),1,val) #; Checking whether there is any more data left If qHandle = "" { Set AtEnd = 1 Set Row = "" Quit $$$OK } #; If not, create %List #; val = $Lb("", Prop1, Prop2) see Storage definition #; Row =$lb(Id,Prop1, Prop2) see ROWSPEC for the AllRecords request Set Row = $Lb(qHandle, $Lg(val,2), $Lg(val,3)) Quit $$$OK } The queryNameClose methodThe queryNameClose method terminates the query, once all the data is obtained. The signature of this method is as follows: ClassMethod queryNameClose(ByRef qHandle As %Binary) As %Status [ PlaceAfter = queryNameFetch ] where: Caché executes this method after the final call to the queryNameFetch methodIn other words, this is a query destructorTherefore you should dispose all SQL cursors, queries and local variables in its implementationThe methods return the current status In our example, we have to delete the local variable qHandle: ClassMethod AllRecordsClose(ByRef qHandle As %Binary) As %Status { Kill qHandle Quit $$$OK } And here we are! Once you compile the class, you will be able to use the AllRecords query from %SQL.Statement – just as the basic class queries. Iteration logic approaches for custom queries So, what approaches can be used for custom queries? In general, there exist 3 basic approaches: Iteration through a globalStatic SQLDynamic SQL Iteration through a globalThe approach is based on using $Order and similar functions for iteration through a global. It can be used in the following cases: Data is stored in globals (without classes)You want to reduce the number of glorefs is the codeThe results must be/can be sorted by the global's subscript Static SQLThe approach is based on cursors and static SQL. This is used for: Making the int code more readableMaking the work with cursors easierSpeeding up the compilation process (static SQL is included into the class query and is therefore compiled only once). Note: Cursors generated from queries of the %SQLQuery type are named automatically, e.g. Q14.All cursors used within a class must have different names.Error messages are related to the internal names of cursors which have an additional characters at the end of their names. For example, an error in cursor Q140 is actually caused by cursor Q14.Use PlaceAfter and make sure that cursors are used in the same int routinewhere they have been declared.INTO must be used in conjunction with FETCH, but not DECLARE. Example of static SQL for Utils.CustomQuery: Query AllStatic() As %Query(CONTAINID = 1, ROWSPEC = "Id:%String,Prop1:%String,Prop2:%Integer") [ SqlName = AllStatic, SqlProc ] { } ClassMethod AllStaticExecute(ByRef qHandle As %Binary) As %Status { &sql(DECLARE C CURSOR FOR SELECT Id, Prop1, Prop2 FROM Utils.CustomQuery ) &sql(OPEN C) Quit $$$OK } ClassMethod AllStaticFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = AllStaticExecute ] { #; INTO must be with FETCH &sql(FETCH C INTO :Id, :Prop1, :Prop2) #; Check if we reached end of data If (SQLCODE'=0) { Set AtEnd = 1 Set Row = "" Quit $$$OK } Set Row = $Lb(Id, Prop1, Prop2) Quit $$$OK } ClassMethod AllStaticClose(ByRef qHandle As %Binary) As %Status [ PlaceAfter = AllStaticFetch ] { &sql(CLOSE C) Quit $$$OK } Dynamic SQLThe approach is based on other class queries and dynamic SQL. This is reasonable when in addition to an SQL query itself, you also need to perform some additional operations, e.g. execute an SQL query in several namespaces or escalate permissions before running the query. Example of dynamic SQL for Utils.CustomQuery: Query AllDynamic() As %Query(CONTAINID = 1, ROWSPEC = "Id:%String,Prop1:%String,Prop2:%Integer") [ SqlName = AllDynamic, SqlProc ] { } ClassMethod AllDynamicExecute(ByRef qHandle As %Binary) As %Status { Set qHandle = ##class(%SQL.Statement).%ExecDirect(,"SELECT * FROM Utils.CustomQuery") Quit $$$OK } ClassMethod AllDynamicFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status { If qHandle.%Next()=0 { Set AtEnd = 1 Set Row = "" Quit $$$OK } Set Row = $Lb(qHandle.%Get("Id"), qHandle.%Get("Prop1"), qHandle.%Get("Prop2")) Quit $$$OK } ClassMethod AllDynamicClose(ByRef qHandle As %Binary) As %Status { Kill qHandle Quit $$$OK } Alternative approach: %SQL.CustomResultSet Alternatively, you can create a query by subclassing from the %SQL.CustomResultSet class. Benefits of this approach are as follows: Slight increase in speedROWSPEC is unnecessary, since all metadata is obtained from the class definitionCompliance with the object-oriented design principles To create query from the subclass of %SQL.CustomResultSet class, make sure to perform the following steps: Define the properties corresponding to the resulting fieldsDefine the private properties where the query context will be storedOverride the %OpenCursor method (similar to queryNameExecute) which initiates the context. In case of any errors, set %SQLCODE and %Message as wellOverride the %Next method (similar to queryNameFetch) which obtains the next result. Fill in the properties. The method returns 0 if all the data has been processed and 1 if some data is still remainingOverride the %CloseCursor method (similar to queryNameClose) if necessary Example of %SQL.CustomResultSet for Utils.CustomQuery: Class Utils.CustomQueryRS Extends %SQL.CustomResultSet { Property Id As %String; Property Prop1 As %String; Property Prop2 As %Integer; Method %OpenCursor() As %Library.Status { Set ..Id = "" Quit $$$OK } Method %Next(ByRef sc As %Library.Status) As %Library.Integer [ PlaceAfter = %Execute ] { Set sc = $$$OK Set ..Id = $Order(^Utils.CustomQueryD(..Id),1,val) Quit:..Id="" 0 Set ..Prop1 = $Lg(val,2) Set ..Prop2 = $Lg(val,3) Quit $$$OK } } You can call it from Caché Object Script code in the following way: Set resultset= ##class(Utils.CustomQueryRS).%New() While resultset.%Next() { Write resultset.Id,! } Another example is available in the SAMPLES namespace – it's the Sample.CustomResultSet class which implements a query for Samples.Person. Summary Custom queries will help you to separate SQL expressions from Caché Object Script code and implement sophisticated behavior which can be too difficult for pure SQL. References Class queries Iteration through a global Static SQL Dynamic SQL %SQL.CustomResultSet The Utils.CustomQuery class The Utils.CustomQueryRS class The author would like to thank Alexander Koblov for his assistance in writing this article. In regards to the first part of your write-up, as a developer, if you want a quick and easy way to test the query from your terminal window (i.e. Cache Terminal, PowerTerm, Putty, Reflections, etc...), then you can run the query as follows: Do ##class(%ResultSet).RunQuery({className},{queryName}) - if you have input parameters, then you would pass those values as subscripts 3 - n; Example of running query with two input parameters: Do ##class(%ResultSet).RunQuery({className},{queryName},{inputValue1},{inputValue2}) So an example of running the first query in your write-up from a terminal window might be: Do ##class(%ResultSet).RunQuery("Sample.Person","ByName","A") The output from the query might be: ID:Name:DOB:SSN:53:Adam,Ralph O.:41730:657-43-6149:33:Adam,Zoe X.:56117:982-36-6928:80:Ahmed,Edgar Q.:33719:546-61-2688:110:Alton,Umberto B.:30116:877-79-1057:146:Avery,Valery P.:39515:310-11-8847: Hope this Helps and Have a Great Day!!! Happy Coding/Testing those queries! Quick followup note - so folks don't freak out about the output from the query example - the names and birthdates and SSN's displayed in the example were from a SAMPLES testing environment where data was auto-generated at random - so the data is fake and not for real people :) Thanks! I often need to run queries from a terminal, so I extended Caché ObjectScript with zsql command to run queries and display the results. Here's how it works: zsql "SELECT TOP 2 Name FROM Sample.Person" Would output: Name Adams,Chris Z. Adams,Danielle P To achieve it I created %ZLANGC00 mac routine with the following code: ; %ZLANGC00 ; custom commands for ObjectScript ; http://docs.intersystems.com/cache20141/csp/docbook/DocBook.UI.Page.cls?KEY=GSTU_customize Quit /// Execute Query and display the results /// Call like this: /// zsql "SELECT TOP 10 Name FROM Sample.Person" ZSQL(Query) #Dim ResultSet As %SQL.StatementResult Set ResultSet = ##class(%SQL.Statement).%ExecDirect(, Query) Do ResultSet.%Display() Quit Save and compile it and then you can execute sql (class queries too) in a terminal with zsql command: zsql "SELECT * FROM Sample.SP_Sample_By_Name('Z')" That said I myself prefer executing SQL queries in SMP because you don't need to type them there (drag&drop from the left panel or copy&paste from the code) - it's very convenient. I typically use the SQL shell in the terminal when doing this. It is very powerful.SAMPLES>do $system.SQL.Shell()SQL Command Line Shell----------------------------------------------------The command prefix is currently set to: <<nothing>>.Enter q to quit, ? for help.SAMPLES>>?Interactive SQL Shell (c) InterSystems Corporation 1999-2009 All Rights Reserved----------------------------------------------------To execute an SQL statement, type it in and press ENTER.To execute a multiline SQL statement, press <enter> to entermultiline statement mode, enter the each statement line andenter GO to exit multiline statement mode and execute the statement.etc...This uses %SQL.Statement to do all the work and has a number of options including saving of queries, etc. I would also recommend to try Caché Web Terminal SQL mode:This mode appeared with 4.0 version. for me personally, the greatest benefit of custom SQL queries is that you don't need any (persistent) data, you can just generate it on the fly, either computing them or bringing from any arbitrary external system. Dan Fantastic post @Eduard.Lebedyuk Alternative approach: %SQL.CustomResultSet is icing on the cake which is not covered by Intersystems documentation. It really should be. This is exactly what I needed for my current project. Thanks. 💡 The article is considered as InterSystems Data Platform Best Practice. For 2017.1CE and later as well as all IRIS versions, %SQL.CustomResultSet should not be used. Instead, use %SQL.CustomQuery. There are several good reasons for this. There is good class documentation available. I am happy to post examples if anyone is interested. Hi @Daniel.Pasco It would be great if you can share some examples with us. Best Regards,Henrique First, keep in mind that all implementations (faithful implementations that is) of %SQL.CustomQuery are also projected as table-valued functions. That means you can include the function in the FROM clause of a SELECT statement. The process of implementing a custom query is simple. These steps are described in the %SQL.CustomQuery class documentation so I'll just summarize here. Define a new class that extends %SQL.CustomQuery; Override the SQLNAME parameter, assign a valid SQL identifier that is to be the name of the TVF; Define properties, in order, that are the columns of each row returned by this query. Let's call these "result columns". Each result column is defined as a non-private property; Define properties that you will need to maintain the source data, pointers, etc. that you will use to manage the data used to produce rows. These properties are defined as "private"; Override %OpenCursor. Add parameters to this method override that correspond to the input parameters that will be passed when instantiating the custom query; Override %FetchCursor. In this method, check for end of data. If not at the end then populate all of the result properties with data and return 1 (true). Otherwise, clear all result properties and return 0; Override %CloseCursor. In this override, release any resources acquired during instantiation and perform any necessary cleanup. I won't post the version of the class that produces this output since the version of %Net.Http in current versions of CE/IRIS do not have a working GetJSON() method. The version of the class I'm posting simply passes in the raw JSON data as an argument. The query: SELECT top 5 stateCode,name,population FROM example_custom.sample_custom_query('https://api.census.gov/data/2014/pep/natstprc?get=STNAME,POP&for=state:*&DATE_=7','Default') ORDER BY population DESC and the results: stateCode name population 06 California 38802500 48 Texas 26956958 12 Florida 19893297 36 New York 19746227 17 Illinois 12880580 5 row(s) affected Using this version of a custom query class: Class example.custom.JsonQuery Extends %SQL.CustomQuery { Parameter SQLNAME As String = "sample_custom_json_query"; Property data As %Library.DynamicAbstractObject [ Private ]; Property iterator As %Iterator.AbstractIterator [ Private ]; Property atEnd As %Integer [ InitialExpression = 0, Private ]; Property stateCode As %String; Property name As %String; Property population As %Integer; Method %OpenCursor(data As %String(MAXLEN="")) [ Private ] { try { if $isobject(data) { set ..data = data } else { set ..data = [].%FromJSON(data) } set ..iterator = ..data.%GetIterator() if '..iterator.%GetNext(.key,.value) { set ..atEnd = 0 set ..iterator = "" } } catch exception { // this is just a place holder, this method reports errors by throwing an exception // but a catch can allow the user to log errors or perform some self-healing action throw exception } } Method %FetchCursor() As %Library.Integer { set response = 0 if ($isObject(..iterator)) && ('..atEnd) { if ..iterator.%GetNext(.key,.value) { set ..name = value.%Get(0) set ..population = value.%Get(1) set ..stateCode = value.%Get(3) set response = 1 } else { set ..atEnd = 1 set ..iterator = "" } } else { set ..name = "" set ..population = "" set ..stateCode = "" } return response } Method %CloseCursor() [ PlaceAfter = %Next, Private ] { // not really necessary as %OnClose will automatically close the cursor during destruction // but users can place code here to clean up other resources allocated for this query instance // that are external to the query instance. Like a temporary global. set ..iterator = "" set ..data = "" } } and this query SELECT top 5 stateCode,name,population FROM example_custom.sample_custom_json_query('[["STNAME","POP","DATE_","state"],["Alabama","4849377","7","01"],["Alaska","736732","7","02"],["Arizona","6731484","7","04"],["Arkansas","2966369","7","05"],["California","38802500","7","06"],["Colorado","5355866","7","08"],["Connecticut","3596677","7","09"],["Delaware","935614","7","10"],["District of Columbia","658893","7","11"],["Florida","19893297","7","12"],["Georgia","10097343","7","13"],["Hawaii","1419561","7","15"],["Idaho","1634464","7","16"],["Illinois","12880580","7","17"],["Indiana","6596855","7","18"],["Iowa","3107126","7","19"],["Kansas","2904021","7","20"],["Kentucky","4413457","7","21"],["Louisiana","4649676","7","22"],["Maine","1330089","7","23"],["Maryland","5976407","7","24"],["Massachusetts","6745408","7","25"],["Michigan","9909877","7","26"],["Minnesota","5457173","7","27"],["Mississippi","2994079","7","28"],["Missouri","6063589","7","29"],["Montana","1023579","7","30"],["Nebraska","1881503","7","31"],["Nevada","2839099","7","32"],["New Hampshire","1326813","7","33"],["New Jersey","8938175","7","34"],["New Mexico","2085572","7","35"],["New York","19746227","7","36"],["North Carolina","9943964","7","37"],["North Dakota","739482","7","38"],["Ohio","11594163","7","39"],["Oklahoma","3878051","7","40"],["Oregon","3970239","7","41"],["Pennsylvania","12787209","7","42"],["Rhode Island","1055173","7","44"],["South Carolina","4832482","7","45"],["South Dakota","853175","7","46"],["Tennessee","6549352","7","47"],["Texas","26956958","7","48"],["Utah","2942902","7","49"],["Vermont","626562","7","50"],["Virginia","8326289","7","51"],["Washington","7061530","7","53"],["West Virginia","1850326","7","54"],["Wisconsin","5757564","7","55"],["Wyoming","584153","7","56"],["Puerto Rico Commonwealth","3548397","7","72"]]') ORDER BY population DESC produces the same result: stateCode name population 06 California 38802500 48 Texas 26956958 12 Florida 19893297 36 New York 19746227 17 Illinois 12880580 5 row(s) affected I am happy to post other examples if you wish. Dan Custom queries can also be instantiated without using SQL. Simply call %New and pass in the arguments that are defined by the %OpenCursor method. There is one difference here - the first argument of %New is the SELECTMODE and subsequent arguments correspond to the %OpenCursor arguments. Once instantiated, the interface is like any other %SQL.IResultSet. USER>set result = ##class(example.custom.Query).%New(,"https://api.census.gov/data/2014/pep/natstprc?get=STNAME,POP&for=state:*&DATE_=7","Default") USER>write result.%Next() 1 USER>write result.name Alabama USER>write result.population 4849377 USER>while result.%Next() { write !,result.name,": ",result.population } Alaska: 736732 Arizona: 6731484 Arkansas: 2966369 California: 38802500 Another unknown feature that isn't mentioned anywhere else. I am a fan Robert...but... https://community.intersystems.com/post/new-video-sql-%E2%80%93-things-you-should-know Somewhere around the 36 minute mark of this video. Buried perhaps. Still, %SQL.CustomQuery has a lot of interesting capabilities. Incredible! I really missed something important!@Daniel.Pasco Thanks for the pointer. I never stop learning. This is a great feature Dan! I'm using it to write SQL queries to Pandas dataframes in Python (code). Some of the reasons why I focus on utilizing class queries include Studio and other editors are much better at providing coloring/syntax checking vs a strategy of setting a tSQL string as some arbitrary SQL statement As mentioned in the original post it provides the separation that allows for easy re-use and testing. If I have a class query I can decide to allow it to be reflected as a stored procedure, I can expose it to ZEN reports, ODBC/JDBC, JSON projection, %XML.DataSet, I can use it to satisfy a control in ZEN that allows for binding to a class query, as well as others. Basically, it provides for great separation. I also like the idea of considering writing the statement using SQL as %Query. If for some reason I run into performance issues that I cannot overcome I can change the implementation to %SQLQuery and implement COS code, the calling application would see the improved performance but does not have to understand the internal implementation. However, I've only done this on extremely rare occasions. I think one of the most important aspects of SQL to always read the query plan, it's there where you can understand what the optimizer is going to do. I care all about the query plan and almost always validate what it reports. Having a class query allows for easy Show Plan examination whereas it's generally hard to do if you take the approach of setting a tSQL string(sometimes with concatenation over several lines). Class Queries are really worth investing in IMHO.
Announcement
Evgeny Shvarov · Dec 7, 2016

InterSystems Developer Community Birthday!

Hi, Community!Today, the 7th of December is the very good day - today is InterSystems Developer Community birthday!One year ago this day we sent tons of email invitations to you, dear members, to join DC.And you joined and hope you like the site!Please feel free to provide your feedback! Please provide only positive below in the comments, for the negative ones we have this page.So, what do we have after a year?How large are we?Here is the picture:We have 2,200 registered members from all over the world, a set of really helpful articles and the working Q&A forum.We have the site which gives us knowledge, experience and sometimes fun!Thank you for your contribution and participation!We can make the place better, please share your ideas too.We have great plans for the next year in Developer Community, stay tuned! Congratulations! Congratz Gratz! Congrats!!the articles and discussions are very useful for all levels of Caché developers. I find it interesting, when I think of Dec 7, I don't think of the Developers Community, I think of the sneak attach on Pearl Harbor, but, maybe I am just getting old. You asked for ideas, one thing I asked for a long time ago and still think it is needed is a Help function on how all of this works. It is not obvious to be sure. I must be getting old also... Actually that is an event that should always be remembered. Good point, Mike! Thank you! We'll do soon. A day that shall live in infamy. You're not old, just an American. I actually baked a cake to commemorate this occasion, and totally not because I'm fat and wanted cake. Hard to believe it's already been a year
Question
Sébastien Demoustiez · Dec 15, 2016

GROUP_CONCAT() With InterSystems Caché

Hello, Is there some way to reproduce the SQL GROUP_CONCAT(http://sql.sh/fonctions/group_concat) with the Caché DB ?Thanks Sébastien Exactly that :) Thanks a lot. Strange but with this function the perfermance are really bad :(0.04s without and 13s with it ... If you want to investigate the performance of the query you can always open a WRC Case (wrc.intersystems.com :-D).Otherwise, send out your class definition and query plan and I can take a cursory look at it. I tried with an other table with just 2 properties ( but more than 1million records too) and that's the same problem.see:http://imgbox.com/Df2WlAPohttp://imgbox.com/tEFMR5V8 Looks like, it works exactly as LIST function in Caché Looking at that documentation, one difference between LIST and GROUP_CONCAT is that GROUP_CONCAT lets you specify the separator, while LIST always uses a comma. If you wanted to use a different separator, and your data will never contain commas, then it's as easy as (for example): select home_city as "City", count(*) as "Count", REPLACE(LIST(Name),',',' ') as "Names" from sample.person group by home_city If "your data will never contain commas" is a bad assumption (as it is in the case of Name in Sample.Person), the solution is to use %DLIST and $ListToString. select home_city as "City", count(*) as "Count", $ListToString(%DLIST(Name),' ') as "Names" from sample.person group by home_city %DLIST builds a $ListBuild list, and $ListToString joins the list elements with the specified separator. %DLIST is useful in other cases too - for example, if your data might contain commas and you want to iterate over the aggregated data after running dynamic SQL.
Announcement
Derek Robinson · Mar 26, 2020

New Podcast: InterSystems Certification

In Episode 6 of Data Points, certification manager Jamie Kantor joins the podcast to tell us all about the InterSystems Certification program, what exams are currently being offered (and what ones are in development), and why it matters for developers and enterprises. Check it out! For more information and to subscribe on your favorite podcast app, head over to https://datapoints.intersystems.com. There, you can also find links to the previous episodes. Make sure to rate the podcast if you're using Apple Podcasts, as well!
Announcement
Yuri Marx · Jun 1, 2020

OData Server for InterSystems IRIS

Now, It is possible expose your persistent classes as OData REST services in seconds. See my app: https://openexchange.intersystems.com/package/OData-Server-for-IRIS. If you like vote in my app on: https://openexchange.intersystems.com/contest/current. If I have votes, I promise add more features. Help me! I don't have votes yet. #IRISContest
Article
Yuri Marx · Aug 12, 2020

InterSystems IRIS Periodic Table

PDF version: https://github.com/yurimarx/iris-periodic-table/raw/master/periodic%20table%20iris.pdf GIT sources: https://github.com/yurimarx/iris-periodic-table InterSystems IRIS is a Data Platform with a lot of features. These features and relevant topics about IRIS is represented in the periodic table elements. A nice colored table but I miss almost all internal used languages: COS is hidden as "Obs", BUT: No BASIC, NO MultiValue, No HTML, No T-SQL / ISQL, no sign of any kind of Networking Also, Globals as THE core store technology seems to be lost. Thanks @Robert.Cemper1003 I wiil improve the table with your tips @Robert.Cemper1003 I improved the table. See if is good now. Thanks your contribution! @Yuri.Gomes Thanks for the quick improvement!Question:Is it possible to have some link behind the boxes ?What I have in mind is a fast directory into Documentation, Subjects in DC, Learning & Training, ...If all 3 three (or more) have it in common as a starting point,then search for help and information could become quite easier. Great idea! I will create a mapped image to allows click in the element and go to the documentation. Thanks, Robert! Will add a few corrections: COS stands for Caché ObjectScript. Now the name of language is InterSystems ObjectScript, so Obs is OK There is no BASIC anymore in IRIS (I think). Globals! This is a must. Yuri! What a beautiful idea! Thank you! If these boxes could be clickable and point to documentation/tag would be a nice features table! Ready for first column! It is clickable. During today I will create for all elements. newSpeak [Orwell 1984} : ISOS - accepted . or ISCOS ? pls. not IOS !! Not that I used BASIC more than for a quick 5 line demo. It is still visible in Studio. the most remarkable feature: it compiles directly to .obj code without touchable intermediate code (.INT) SUPER! works excellent! A strong improvement for Docs. Finally a serious follower to the FeatureMap we have seen last on C/E 2015.2 https://cedocs.intersystems.com/ens20152/csp/docbook/featuremapCache.csp Nice sample. This give me an idea to create a treemap mixed with heatmap as a web app. Wow! So fast! Thank you, Yuri! Wow! That's great! How to turn a png file into a web app idea Hi Yuri, The PDF link doesn't work. Link adjusted now. Thanks to report me. This is so cool! Thanks @Joseph.Lichtenberg! It's a fantastic idea. Remember old times. Thanks Andre Very Nicely presented, It shows your passion on Intersystem. KUDOS Thanks!
Announcement
Steven LeBlanc · Aug 21, 2020

Introducing InterSystems Container Registry

I am pleased to announce the availability of InterSystems Container Registry. This provides a new distribution channel for customers to access container-based releases and previews. All Community Edition images are available in a public repository with no login required. All full released images (IRIS, IRIS for Health, Health Connect, System Alerting and Monitoring, InterSystems Cloud Manager) and utility images (such as arbiter, Web Gateway, and PasswordHash) require a login token, generated from your WRC account credentials. The WRC Distributions site will continue to provide released images as tarballs for the time being. However, you can now configure your CI/CD pipelines to ‘docker pull’ images directly from InterSystems Container Registry. The registry can be accessed at https://containers.intersystems.com. Please refer below or to the documentation (Using the InterSystems Container Registry) for full usage instructions. If you run into any issue or have any feedback to share please let us know in the comments below, or contact support@intersystems.com. -------------------------------------------------------------- Using the InterSystems Container Registry This document provides instructions for using InterSystems Container Registry (ICR), located at containers.intersystems.com. Images in the ICR can be downloaded with the docker pull command, for example: docker pull containers.intersystems.com/intersystems/iris-community:2020.4.0.547.0 For a full listing of all available images, please refer to Container Images Available from InterSystems This document contains the following sections: Authenticating to the ICR Listing the ICR Inventory Authenticating to the ICR To log into the ICR, take the following steps: Load https://containers.intersystems.com/ in your browser and log in with your InterSystems/WRC credentials. Retrieve your Docker login token, or the full login command. In your Docker interface (for example, your PowerShell window or Linux command line), authenticate to the ICR using the provided credentials. You can do this by copying and pasting the full docker login command displayed, for example: docker login -u="bbinstoc" -p="provided_password" containers.intersystems.com For security reasons, however, you may want to instead enter the command docker login containers.intersystems.com, then enter your username at the Username prompt and paste your password into the Password: prompt. Note: If you are logged into another Docker registry, the docker login command may result in an error; log out of the other registry before logging into containers.intersystems.com. You can now pull images from the ICR, for example: docker pull containers.intersystems.com/intersystems/iris:2020.4.0.547.0 Listing the ICR Inventory APIs are available to list images and tags in a Docker registry. An example of an open source third-party utility that can be used to list a registry’s inventory is docker-ls, available at https://github.com/mayflower/docker-ls. There are several ways to obtain this utility. You can: Download precompiled docker-ls binaries for a variety of platforms. Install the utility directly on some platforms, for example on Linux systems with the command sudo snap install docker-ls Pull and run the image carinadigital/docker-ls:latest on Linux platforms to install the utility, for example: docker run --rm carinadigital/docker-ls:latest Once docker-ls is installed, you can use the following command to list the repositories in the ICR: docker-ls repositories --registry https://containers.intersystems.com --user username --password password Note: Use the --interactive-password option to be prompted for the password rather than including it on the command line. To list only the publicly available images, provide empty strings ("") as arguments to the --user and --password options, for example, the following lists only the tags of public InterSystems IRIS for Health images: docker-ls tags --registry https://containers.intersystems.com --user "" --password "" intersystems/irishealth-community If you wish to see the full list of non-public images, you will need to provide your username and password to this utility regardless of whether you are logged into containers.intersystems.com. Further examples are available at https://github.com/mayflower/docker-ls Error response from daemon: Get https://containers.intersystems.com/v2/: unauthorized: BAD_CREDENTIAL Hi, it's possible you're still logged into another registry. Can you try a 'docker logout' prior to attempting to access containers.intersystems.com? I have logged out and resume to login, the message is: WARNING! Using --password via the CLI is insecure. Use --password-stdin.Error response from daemon: Get https://containers.intersystems.com/v2/: unauthorized: BAD_CREDENTIAL Hi Abdullah,We needed to link your user account with your organization.That should be all set now, please let us know if you have any further issues. Error response from daemon: Get https://containers.intersystems.com/v2/: unauthorized: BAD_CREDENTIAL Even after another docker logout? Please reach out to the WRC to help with your authentication issue. thank you a lot, it is succeeded and I would like to send you the message: WARNING! Using --password via the CLI is insecure. Use --password-stdin.WARNING! Your password will be stored unencrypted in /root/snap/docker/471/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded But I have another Problem as I have done: docker-compose build: Step 1/16 : FROM containers.intersystems.com/intersystems/webgateway:2020.2.0.211.0ERROR: Service 'webserver' failed to build : manifest for containers.intersystems.com/intersystems/webgateway:2020.2.0.211.0 not found: manifest unknown: The named manifest is not known to the registry. I found that installing using "snap" installs a older version that does not support using the results of a previous 'docker login' command. Getting the latest version from https://github.com/mayflower/docker-ls/releases works. For those of you that like GUI tools in an IDE, I just installed the Microsoft Docker extension for VS Code. It shows my Containers and Images just like Docker Desktop Dashboard does, and lets me start/stop/launch CLI/inspect etc. But the real reason I installed it is because there's also a Registries section with a Connect Registry icon (looks like a plug). Using that, I chose "Generic Docker Registry" (other choices: Azure, Docker Hub, GitLab). I supplied the registry URL. It prompted me for my username and password (Docker login token as described above) and I can now browse the registry. Beautiful! I have this error in my WSL:~$ docker pull containers.intersystems.com/intersystems/webgateway:2021.1.0.205.0Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? I am so sorry, that's because I haven't run Docker yet I got that every time unless I did sudo for the docker pull. Steven, I'm getting this even after doing a docker logout too. Same error, BAD_CREDENTIAL. I see there's a comment above about linking an account to an organization. Do I need to do that? Hi David, yes I believe you'll need to contact the WRC to make sure that your email/login is linked to a supported organization, as that's required in order to access non-community images in the registry. You can contact support@intersystems.com and they can help straighten this out for you. If you are otherwise intending to access Community Edition images, you shouldn't need to log in at all. In Linux, create a docker group and add your user to that. This should enable you to do docker without sudo.