查找

问题
· 14 hr 前

How to create a user via ObjectScript for the instance and specify roles and namespace?

I am trying to create users who only have `%SQL` Role for the INSTANCE. But I am unable to find any documentation on the ` Security.Users` class.

See:

    // Instantiate the Security.Users object
    Set userObj = ##class(Security.Users).%New()    
    // Set the username and password
    Set userObj.Name = userName
    Set userObj.FullName = userFullName
    Set userObj.Namespace = "USER"
    Set userObj.Roles = "%SQL"
    Set sc = userObj.ChangePassword(passwd)    
    // Save the user to the database
    Set ss = userObj.%Save()

I cant figure out the "Namespace" property for this class, let alone assign a password. Any help would be appreciated. Also the `ChangePassword` method does not appear to work.

1 条新评论
讨论 (1)2
登录或注册以继续
公告
· 15 hr 前

[Video] From Idea to Impact: The InterSystems Approach

Hi Community,

Enjoy the new video on InterSystems Developers YouTube:

⏯  From Idea to Impact: The InterSystems Approach @ Global Summit 2024

Tune in for the discussion of the structured approach to accelerating innovation within the company, emphasizing culture, process, and execution using InterSystems technologies. Innovation tournaments, speed brainstorming, innovation loops, and test beds are used to drive idea development from inception to impact.

Presenters:
🗣 @Jeff Fried, Director, Platform Strategy, InterSystems
🗣 @Alki Iliopoulou, Innovation Ecosystem Leader, InterSystems

Stay ahead of the curve! Watch the video and subscribe to keep learning! 

讨论 (0)1
登录或注册以继续
文章
· 18 hr 前 阅读大约需 23 分钟

InterSystems IRIS JSON

JSON

JSON (JavaScript Object Notation) is a lightweight, text-based format designed for structured data interchange. It represents data objects consisting of key–value pairs and arrays, and it is entirely language-independent.

JSON Datatypes

JSON consists of six fundamental data types used to represent structured data:

  1. String
  • It is a text enclosed in double quotes. For example, "name": "Alice".
  1. Number
  • It is integers or floating-point numbers.
  • They have no quotes, no leading zeros (e.g., 03562), and no special values like NaN or Infinity. For instance, "age": 30, "score": 95.5.
  1. Boolean
  • It represents logical values: true or false (without quotes). For example, "isActive": true.
  1. Null
  • It symbolizes a null or an empty value. For instance, "middleName": null.
  1. Array
  • It is an ordered list of values (can be of any data type, including nested arrays/objects). For example, "colors": ["red", "green", "blue",{ "additional": "black" },"1Bx124s"].
  1. Object
  • It is a collection of key/value pairs (e.g., a dictionary or map).
  • Keys must be strings, whereas values can be any JSON type. Example:

How InterSystems IRIS Creates and Manipulates JSON

InterSystems IRIS provides several simple and efficient methods for creating and interacting with standard JSON data structures:

  1. JSON literal constructors in ObjectScript syntax
  2. %DynamicObject and %DynamicArray class definitions with their APIs for serialization and deserialization
  3. JSON_OBJECT, JSON_ARRAYAGG and JSON_TABLE functions for SQL

JSON Literal Constructors

JSON literal constructors in ObjectScript syntax enable the creation and modification of JSON structures in a highly flexible and intuitive manner. This approach allows you to define dynamic entities by directly assigning a JSON string to a variable, simplifying JSON data handling.

When JSON is created using literal constructors, InterSystems IRIS automatically instantiates the appropriate %DynamicObject and %DynamicArray object classes. It provides direct access to object model capabilities, allowing you to manipulate instance methods without explicit object creation.

Dynamic Object Example

Multiple Ways to Construct JSON in IRIS

InterSystems IRIS offers flexibility in how you construct and assign JSON data. You can either use a single-line literal constructor or build the JSON object step-by-step utilizing dynamic object syntax. The resulting structure is always a fully-typed %DynamicObject that inherits all the behaviors and methods available to %DynamicObject.

Method 1: Literal JSON Construction

You can define the entire JSON structure in one line, including ObjectScript expressions that are evaluated at runtime:set json =

Set json= {

    "name": "test,patient",

    "title": "Mr",

    "p_age": ($H - $ZDateH("12/01/1990") \ 365),

“isActive”: true

}

In this example the values stand for the following:

  • "p_age" is an expression evaluated at runtime, based on the difference between the current date ($Horolog) and a specific birth date.
  • "isActive" directly declares a JSON Boolean true value.

 

Method 2: Step-by-Step Dynamic Assignment

Alternatively, you can build the JSON object by setting each key-value pair individually:

Set json = {}
Set json.name = "test,patient"
Set json.title = "Mr"
Set json."p_age" = ($Horolog - $ZDateH("12/01/1990") \ 365)

This approach is helpful in the following cases:

  • Values are derived conditionally.
  • You want to build the object incrementally.
  • Code clarity and maintainability are priorities.

Method 3: Build a DynamicObject Using Methods

You can build a %DynamicObject incrementally with the help of the %Set() method that lets you define the values below:

  • The key (1st argument)
  • The value (2nd argument)
  • The data type (optional 3rd argument)

To ensure the correct JSON data type is employed for the value, you can explicitly specify the type as the third parameter.

Set json = {}
Do json.%Set("name", "test,patient")
Do json.%Set("title", "Mr ")
Do json.%Set("p_age",  ($Horolog - $ZDateH("12/01/1990") \ 365), "number")
Do json.%Set(“IsActive”,1,”Boolean”)

 

Dynamic Array Construction in IRIS

Similar to dynamic objects, dynamic arrays in InterSystems IRIS can be constructed with either a single-line literal constructor or a step-by-step dynamic assignment approach.These arrays are instances of %DynamicArray and can hold mixed data types, including objects, numbers, strings, booleans, and runtime expressions.

Method 1: Literal JSON Array Construction

You can define a JSON array in a single line utilizing the array literal syntax. The resulting structure is a fully-typed %DynamicArray object that inherits all the behaviors and methods available to %DynamicArray.


set array = [1, "test", 12.32565, 0.01548, {"name": "test"}, 1.00000, ($ZVersion), true]

Note for this example:

  • The array includes integers, strings, decimals, a nested object, a runtime-evaluated expression ($ZVersion), and a Boolean.

Method 2: Step-by-Step Dynamic Assignment

Method 2.1: Set Values in a Dynamic Array by Index

A %DynamicArray in InterSystems IRIS is an ordered collection of values, where each element is accessed by its index, starting from 0.

You can assign values directly to specific indices. If you skip any intermediate positions, those indices remain unassigned internally. However, for serialization purposes (e.g., when using ZWrite or %ToJSON()), IRIS automatically displays unassigned elements as null to maintain a valid JSON structure.

This means there is a distinction between how the data is stored and how it is represented: unassigned elements are not truly null unless explicitly set, but they appear as null when the array is output or serialized. You can determine the type of a value using the %GetTypeOf() method.

Example:

USER>Set array = []
USER>Set array."1" = "test" ; assigned into index 1
USER>Set array."5" = "hello" ; assigned into index 5
USER>Write array.%ToJSON()
array=[null,"test",null,null,null,"hello"] 

 

Although the output shows null at index 0, it is crucial to note that the value was never explicitly set. Therefore, calling array.%GetTypeOf(0) will return "unassigned", indicating that the index exists only for display purposes and has not been initialized with a value.

Method 2.2: Build a DynamicArray Using Methods

You can incrementally construct a %DynamicArray by using the built-in %Push() method. This approach appends values to the end of the array in the order they are added.

set array = []
do array.%Push(1)
do array.%Push("test")
do array.%Push({"name": "test"})
do array.%Push($Piece($zversion, " ", 1, 5))
Do array.%ToJSON()
#;
Output 
[1,"test",{"name":"test"},"IRIS for Windows (x86-64) 2024.1.1"]

This method is practical in the following cases:

  • Array elements are determined dynamically.
  • You are constructing the array conditionally or iteratively.
  • You want more control over the data being inserted.

Detailed Overview of JSON Key-Value Assignment

Assigning Runtime Values in JSON (IRIS)

InterSystems IRIS supports both static and dynamic value assignment within JSON structures. When working with the literal constructor syntax ({} or []), any extended expression enclosed in parentheses is evaluated at runtime.

For example:

USER>Set json = {"version":($ZVersion)}

USER>ZWrite json ; print the entire JSON
json={"version":"IRIS for Windows (x86-64) 2024.1.1 (Build 347U) Thu Jul 18 2024 17:40:10 EDT"}  ; <DYNAMIC OBJECT>

In this case, the value of the "version" key is dynamically evaluated using the $ZVersion system variable at runtime. it allows you to embed real-time system or application data directly into your JSON structures.

Number Representation and Assignment in JSON

An ObjectScript Decimal Floating-Point number and an IEEE Binary Floating-Point number do not track trailing zeros in decimal representation (e.g., 12.3, 12.30, and 12.3000). However, in JSON, numbers are represented as text in decimal or scientific notation (aka exponent form). While JSON syntax supports scientific notation (e.g., 1.23e4), it does not mandate any internal binary representation. It means that JSON numbers can preserve trailing zeros when created using literal constructors with square brackets [] or curly braces {}, as these constructors parse values utilizing JSON syntax that maintains formatting details. Chek out the example below:

USER> Set json = {"decimal":1.00000}
USER> ZWrite json 
{"decimal":1.00000}  ; <DYNAMIC OBJECT>

Here, the trailing zeros are preserved in the JSON object representation.

Scientific Notation

InterSystems IRIS preserves scientific notation and trailing zeros in JSON, allowing you to set and view values in exponent form. The number retains this format until it is explicitly written or serialized.

However, note that numbers supported by JSON can exceed the capacity of the internal representations backed by ObjectScript. Rounding or overflow can occur when converting a JSON numeric value for use in an ObjectScript expression. For example:

USER>SET z=[3E400]  ; No error placing a large JSON number into a %DynamicArray

USER>WRITE z.%Get(0)  ; But converting the JSON number gets a <MAXNUMBER> signal

Step-by-Step Way

 

USER>Set json = {} 
USER>Set json."e_exponent"=1E5
USER>ZWrite json
json={"e_exponent":100000}  ; <DYNAMIC OBJECT>

In this example, the following happens:

  • The value 1E5 (scientific notation for 100,000) is treated as a numeric expression.
  • IRIS evaluates the dynamic expression at runtime and stores the computed result (100000) as the actual value of the "e_exponent" key.

Unicode Translation

Unicode Handling in Literal Constructors – IRIS JSON

In InterSystems IRIS, when working with the literal constructor syntax for dynamic arrays, each element is assessed at runtime. It means that you can mix standard JSON strings and ObjectScript expressions, including those involving Unicode characters, and IRIS will store the evaluated results.

Example: Mixed Input, Same Result

USER>Set array = ["\u00E9", "cach\u00E9", ("cach"_$CHAR(233))]
USER>ZWrite array
array=["é","caché","caché"]  ; <DYNAMIC ARRAY>
  • "\u00E9" is interpreted as the Unicode character é.
  • "cach\u00E9" becomes caché when parsed.
  • ("cach"_$CHAR(233)) is an ObjectScript expression that concatenates "cach" with the character é (Unicode 233).

All three inputs result in identical strings: "é" and "caché".

When Unicode Escapes Are Passed as Expressions

If you wrap a Unicode escape string in parentheses (making it an expression), IRIS treats it as a plain string literal, not as a Unicode escape.

USER>Set array = ["cach\u00E9", ("cach\u00E9")]
USER>ZWrite array
array=["caché","cach\\u00E9"]  ; <DYNAMIC ARRAY>

 

  • The first element "cach\u00E9" string literal is parsed as JSON and becomes caché. When a string literal directly appears as an element within the literal constructor syntax (which functions as a JSON array literal in ObjectScript), IRIS treats this as a JSON string literal context
  • The second element ("cach\u00E9") is treated as a ObjectScript string literal and it evaluated as runtime expression, so the \u is not parsed as Unicode. It stays escaped as \\u00E9.

Assign Null Values

IRIS provides a straightforward way to assign a null value to a key in a JSON key-value pair.

For example:

USER>Set json = {"isActive":null}
USER>ZWrite json
json={"isActive":null}  ; <DYNAMIC OBJECT>

It sets the "isActive" key to null within the JSON object, with the help of the native dynamic object syntax in IRIS.

Using Comments Inside JSON Constructors in IRIS

Unlike strict JSON parsers (which do not allow any comments), InterSystems IRIS provides the flexibility to include comments within JSON literal constructors ({} or []). It can significantly enhance code readability and maintainability.

Block Comments (/* */) in Arrays and Objects

IRIS allows you to insert block-style comments (/* comment */) anywhere within JSON constructors (both arrays and objects). However, note that // line comments are not allowed inside single-line array/object declarations.

set array = [1, "test" /* test comment */, "hello world", ($Horolog)]

set array = [

1"test" /* test comment */"Hello world", 

($Horolog) // Internal date and time format
]

 

  • It is valid in IRIS.
  • It is useful for documenting array elements.

Block and Line Comments in JSON Objects

IRIS also allows both /* block comments */ and // line comments inside object constructors:

set json = {

    "name": "test", /* test name */
    "age": (age)  // age will be calculated at runtime
}
  • /* ... */ can be used after any key-value pair.
  • // ... can be placed after a pair as well

Create JSON with Class Definitions 

The %DynamicAbstractObject (%DAO) subclasses, including the %DynamicArray and %DynamicObject classes, are the primary classes for creating, modifying, and sending JSON representations into and out of InterSystems IRIS databases.

These classes support object manipulation using such ObjectScript intrinsic functions as $Property and $Method.The %DynamicObject implementation does not maintain a predefined list of valid property names, as all string keys are considered legal and valid.

Instead of employing %Get and %Set dedicated methods for DynamicObject and DynamicArray, you can also retrieve values dynamically with the $Property and $Method intrinsic functions.

However, $Property is generally more efficient than $Method, and is therefore recommended when accessing values in %DynamicObject instances.

ClassMethod sample()
{
    #dynamic object
	Set do =  {"1D":"test"}
	Set $Property(do, "id")=12
	Do $Method(do, "%Set", "version", $ZV, "string")
	ZWrite do
	#; Dynamic Array
	Set da = []
	#; Here the property should be the index of the array
	Set $Property(da, "0")=12
	Do $Method(da, "%Set", "4", $ZV)
	Zwrite da
}


DynamicObject

USER>Set do = {"1D":"test","version":($Piece($ZVersion," ",1,5))}
USER>Write $Property(do,"1D")
test
USER>Write $Method(do,"versionGet")
IRIS for Windows (x86-64) 2024.1.1


DynamicArray

USER>Set da = [1,($USERNAME),($ROLES)]
USER>Write $Property(da,1)
Test
USER>Write $Method(da,"%Get",2)
All

Code Sample

The following provides ObjectScript and Embedded Python code samples for %DynamicObject creation (for IRIS 2024.1 and 2025.1 versions).

Set dynObject1 = ##class(%DynamicObject).%New()
Set dynObject1.MRN = 4298598
Set dynObject1.name = "test,Patient A"
Set dynObject1.IsActive = 1
Set dynObject1.emails = ##class(%DynamicArray).%New()
Set dynObject1. emails."0" = "test@gmail.com"
Set dynObject1. emails."1" = “test1@gmail.com”

Embedded Python sample

import iris

dynObject1 = iris.cls("%DynamicObject")._New()
dynObject1._Set("MRN",298598) # inovke IRIS %DynamicObject object %Set method
dynObject1._Set("name" , "test,Patient A")
dynObject1._Set("IsActive", 1, "boolean")
# no native python set method available
emails = iris.cls("%DynamicArray")._New()
emails.add("test@gmail.com") #native python function
emails.add("test1@gmail.com")
dynObject1._Set("emails", emails)
print(dynObject1.toString())

 

Embedded Python 2025.1

Simplified Class Method Access in Python

Instead of operating the iris.cls("ClassName").method() syntax, you can directly access class methods with the iris.ClassName.method() format for improved readability and convenience.

# Traditional syntax

iris.cls("Sample.Person")._New()

# Simplified syntax

iris.Sample.Person._New()

# For system classes

iris.cls("%DynamicObject")._New()

iris._Library.DynamicObject._New()

This approach provides a more Pythonic and concise way to interact with InterSystems IRIS classes.

2025.1 Embedded Python sample

import iris
#DynamicObject  
dynObject1 = iris._Library.DynamicObject._New()
dynObject1._Set("MRN",298598)
dynObject1._Set("name" , "test,Patient A")
dynObject1._Set("IsActive", 1, "boolean")
#DynamicArray
emails = iris._Library.DynamicArray._New()
emails.add("test@gmail.com")
emails.add("test1@gmail.com")
dynObject1._Set("emails", emails)
print(dynObject1.toString())

Methods of %DynamicObject and %DynamicArray

A set of commonly used and practical methods is available for working with JSON in InterSystems IRIS. These methods are essential for efficiently creating, modifying, and deleting JSON objects and arrays.

%IsDefined(Key)

The %IsDefined method checks whether a specified key exists in the object. It returns a Boolean value: 1 if the key is present, or 0 if it is not. Note that key matching is case-sensitive.

USER>Set json = {"username":"TestUser", "role":"All"}
USER>Write json.%IsDefined("username")
1
USER>Write json.%IsDefined("password")
0
USER>Write json.%IsDefined("userName")
0

Embedded Python - contains(key)

The Python contains function checks if a specified key exists in a DynamicObject or DynamicArray. It returns 1 if the key is present, and 0 if it is not.

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DAOIsDefined()
{
    Set json  = {"username":($USERNAME), "roles": ($ROLES), "horolog":(+$H)}
    Do ..DAOIsDefinedPY(json,"horolog")
}
ClassMethod DAOIsDefinedPY(dao, key) [ Language = python ]
{
    # use contains instead of %IsDefined method
    print(dao.contains(key))
}
}

 

Output
USER>DO ##class(Sample.DAO.EmpeddedPY).DAOIsDefined()
1

 

%Get(Key, Default, Type)

The %Get is an instance method used to retrieve values from a %DynamicObject or %DynamicArray. When you work with the %Get(key) method to evaluate a property containing a JSON representation, that JSON representation will first be converted into an ObjectScript value, and then it will return that value.

This method accepts 3 formal parameters:

  1. Key (required)
  • objects: the name of the key to retrieve.
  • arrays: the index position of the element.
  1. Default (optional)
  • The value to return if the key or index is not present.
  • If omitted and the key is missing, an empty string is returned.
  1. Type (optional but important)
  • This is the most crucial parameter when handling large strings. If the JSON contains a large string exceeding the IRIS maximum string length (3,641,144), get the maxstring by ($SYSTEM.SYS.MaxLocalLength() / $$$MaxLocalLength / $$$MaxStringLength).  You can also pass this parameter with one of the following values to prevent a <MAXSTRING> error:

"string"       - Convert to text string
"string>base64"    - Convert to text string, then encode into base64
"string<base64"    - Convert to text string, then decode from base64
"stream"     - Place string conversion into %Stream
"stream>base64"   - String encoded into base64 into %Stream
"stream<base64"   - String decoded from base64 into %Stream
"json"       - Convert to JSON representation

Apart from the abovementioned types, it might also signal < ILLEGAL VALUE> error in the next cases:

  • To handle large string values efficiently, use the "stream" type. It returns a stream object (e.g., %Stream.DynamicCharacter) instead of loading the entire string into memory.

Example: Set stream = json.%Get("image", , "stream")

  • If you want to retrieve the value as a Base64-encoded string, go for the "string>base64" type. Example: Set data = json.%Get("image", , "string>base64")
  • To decode a Base64-encoded string and get the original value, utilize the "string<base64" type. Example: Set data= json.%Get("b64_encode", , "string<base64")
  • By default, %Get converts JSON values to their corresponding ObjectScript types. To retrieve the original JSON representation instead (e.g., true, null), specify "JSON" as the third parameter. Here is how it works in detail:

Set json = {"IsActive": true, "IsNull": null}

By default, retrieving "IsActive" returns 1, and "IsNull" returns an empty string (""). It happens because JSON values are automatically converted to their ObjectScript equivalents.

To retrieve the original JSON representations (true and null), pass "JSON" as the third parameter in the %Get method:

USER>Set json = {"IsActive": true, "IsNull": null}
USER>Write json.%Get("IsActive") ; returns 1
1
USER>Write json.%Get("IsActive",,"JSON") ; returns true
true
USER>Write json.%Get("IsNull") ; returns "" 
USER>Write json.%Get("IsNull", , "JSON") ; returns null
null

Generate Large JSON

The following code generates a large sample JSON as a stream.

ClassMethod LargeJSON()
{
	Set $Piece(data,"a",$$$MaxStringLength)=""
	#; create a stream object and it has json string {"data":""} 
	Set stream = ##class(%Stream.TmpCharacter).%New()
	Do stream.Write("{""data"": "" ")
	For i=1:1:20 d stream.Write(data)
	Do stream.Write(" ""} ") 
    Quit stream
}


Once a stream is created, convert it to JSON with the help of the %FromJSON() method. When you work with %Get() to fetch by JSON key, it might signal a <MAXSTRING> error. To prevent this, you need to pass the third parameter as "stream", and it will convert the string into a stream object (%Stream.DynamicBinary).

What is %Stream.DynamicBinary and %Stream.DynamicCharacter?

The %Stream.DynamicCharacter (%SDC) and %Stream.DynamicBinary (%SDB) classes are specifically designed to hold copies of string or binary data stored within elements of a %DynamicArray (%DA) or %DynamicObject (%DO).

These %SDC and %SDB streams are read-only, meaning their contents cannot be modified directly. However, if you need to alter the data, you can create a writable stream from the %Stream package and use the CopyFrom() method to duplicate the contents from the read-only stream into the new writable stream.

ClassMethod ParseToJSON()
{
	Set stream = ..LargeJSON()
	Set json = ##class(%DynamicAbstractObject).%FromJSON(stream)
	Write json
	Write json.%Get("data") ; it signals <MAXSTRING> error
    #; to prevent this
    Write json.%Get("data",,"stream") ; it returns a stream object
}

 

Embedded Python

DynamicObject

Embedded Python - get(key)

The Python get function takes one argument — the key to check for in the dynamic object.

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{

ClassMethod DOGet()
{
	Set json = {"id":1234,"firstName":"Ashok","lastName":"Kumar","IsActive":true}
	Do ..DOGetPY(json)
}

/// DynamicObject set python
ClassMethod DOGetPY(dynamicObj) [ Language = python ]
{
	print(dynamicObj._Get("IsActive",1,"JSON"))
	# get has one parameter
	print(dynamicObj.get("id"))
}

ClassMethod DAOGet()
{
	Set json  ={"string":"Hello, world!","number_integer":42,
					"number_float":3.1415899999999999,"boolean_true":true,
					"boolean_false":false,"null_value":null,
					"object":{"nested_key":"nested value"},
					"array":[1,"two",true,null,{"key":"value"}]
				}
	Do ..DAOGetPY(json,"array")
}

ClassMethod DAOGetPY(dao, key) [ Language = python ]
{
	# Use the Python-specific function "get" to retrieve values from the DynamicObject/ array. No need to use %Get
	print(dao.get(key).get(4).get("key"))
	return 0
}
}

 

Output
USER>do ##class(Sample.DAO.EmpeddedPY).DOGet()
true
1234
USER>do ##class(Sample.DAO.EmpeddedPY).DAOGet()
value

DynamicArray 

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DAGet()
{
	Set array = [1234,"ashok","kumar",{"version":($ZVersion)}]
	Do ..DAGetPY(array)
}

/// DynamicObject set python
ClassMethod DAGetPY(dynamicArr) [ Language = python ]
{
	print(dynamicArr._Get(1))
	print(dynamicArr.get(3)._ToJSON())
}
}

 

Output
USER>do ##class(Sample.DAO.EmpeddedPY).DAGet()
ashok
{"version":"IRIS for Windows (x86-64) 2024.1.1 (Build 347U) Thu Jul 18 2024 17:40:10 EDT"}

%Set(Key, Value, Type)

The %Set instance method is used to add or modify key-value pairs in a %DynamicObject, or set indexed values in a %DynamicArray. The value assigned is evaluated as a runtime ObjectScript expression, and the result of that expression becomes the property's value.

This %Set has 3 formal parameters:

  1. Key (required): Represents the key in a %DynamicObject or the index in a %DynamicArray. In JSON, all object keys must be strings. If you provide a numeric key (e.g., 1), it will automatically be converted to a string.

Example: Do json.%Set(1, "test") results in {"1": "test"}.

  1. Value (required): The actual value that will be stored in the element. Omitting this will signal a <PARAMETER> error.
  2. Type (optional): This parameter helps enforce correct JSON data types during assignment. It is particularly necessary when dealing with Booleans, nulls, large strings, or stream objects.
  • Boolean: To set a Boolean key-value pair in JSON, note that InterSystems IRIS does not have a native Boolean type. You can pass 1 for true and specify the type as "Boolean" to store the value correctly.

Example: Do json.%Set("active", 1, "Boolean") results in {"active":true}.

  • Number: To store a string as a JSON number, provide the value as a string and specify the type as "Number".

Example: Do json.%Set("int", "158425", "Number").

  • Null: In IRIS, a string with a space (" ") is not automatically treated as null. To explicitly set a JSON null, use a blank string with the type "null".

Example: Do json.%Set("IsNull", "", "null") results in {"IsNull": null}.

  • Stream: If the value is a stream object, you can specify the type as "stream" to automatically convert the stream content to a string before storing it in the JSON object.
  • String and numeric values can be assigned directly without specifying a type. 
  • Base64 Encoding/Decoding: To encode a string as a Base64 value before storing it, utilize the type "string>base64".

Example: Do json.%Set("basicpassword", "_BASIC:TEST","string>base64").

  • To decode a Base64 string and store the result, employ the type "string<base64".

Example: Do json.%Set("basicpassword", "X0JBU0lDOlRFU1Q=","string<base64").

  • For stream content: "stream>base64"- %Stream contents are encoded into a Base64 string.
  • "stream<base64"- %Stream is decoded from Base64 into a byte string.

Embedded Python

In embedded Python, you must use an underscore _ instead of a percent sign % for methods. For instance, %Get() becomes _Get() in a Python script.

DynamicObject

Embedded Python - put(key, value)

The Python put function takes two arguments: The first is the key (for a DynamicObject) or index (for a DynamicArray), and the second is the value to assign to that key or index.

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DOSet()
{
	Set json = {}
	Do ..DOSetPY(json)
	Write json.%ToJSON()
}

/// simple set in Python
ClassMethod DOSetPY(dynamicObj) [ Language = python ]
{
	dynamicObj._Set("id",1234)
	dynamicObj._Set("firstName", "Ashok")
	dynamicObj.put("lastName", "Kumar")
	#print(dynamicObj._ToJSON())
}

ClassMethod DAOSet()
{
	Set json  ={"string":"Hello, world!","number_integer":42,
					"object":{"nested_key":"nested value"},
					"array":[1,"two",true,null,{"key":"value"}]
				}
	Do ..DAOSetPY(json,"array")
}
/// chaining function usage
ClassMethod DAOSetPY(dao, key) [ Language = python ]
{
	# Use the Python-specific function "put" to retrieve values from the DynamicObject/ array. No need to use %Set
	dao.get(key).get(4).put("key","changed to hello")
	# use toString() function . No need to use %ToJSON()
	print(dao.toString())
	return 0
}
}

 

Output
USER> Do ##class(Sample.DAO.EmpeddedPY).DOSet()
{"id":1234,"firstName":"Ashok","lastName":"Kumar"}
USER>do ##class(Sample.DAO.EmpeddedPY).DAOSet()
{"string":"Hello, world!","number_integer":42,"object":{"nested_key":"nested value"},"array":[1,"two",true,null,{"key":"changed to hello"}]}


DynamicArray

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DASet()
{
	Set array = ##class(%DynamicArray).%New()
	Do ..DASetPY(array)
	Write array.%ToJSON()
}

/// DynamicObject set Python
ClassMethod DASetPY(dynamicArr) [ Language = python ]
{
	dynamicArr._Set(0, 1234)
	dynamicArr._Set(1, "Ashok")
	dynamicArr.put(2, "Kumar")
	#print(dynamicObj._ToJSON())
}
}

 

Output
USER> Do ##class(Sample.DAO.EmpeddedPY).DASet()
[1234,"Ashok","Kumar"]
USER>do ##class(Sample.DAO.EmpeddedPY).DAOSet()
{"string":"Hello, world!","number_integer":42,"object":{"nested_key":"nested value"},"array":[1,"two",true,null,{"key":"changed to hello"}]}

Important Note: When using %Set(key, value) to modify a property, the value is computed as a runtime ObjectScript expression, and the result of that computation becomes the property's value.

Method Chaining

Such methods as %Set() and %Push() return chainable references and can be called from anywhere in the chain.

USER>Set jstring = "[123]"
USER>Write [].%FromJSON(jstring).%Set(1,"one").%Push("two").%Push("three").%Set(1,"final value").%ToJSON()
[123,"final value","two","three"]

%Push(Value, Type)

The %Push instance method appends the given value to the end of the current array, increasing its length.

This method has two formal parameters:

  1. Value (required): The actual value to be inserted at the end of the array. This value can be a JSON string, number, Boolean, or JSON object. Type (optional): This parameter helps enforce correct JSON data types during assignment. It is particularly critical when dealing with Booleans, nulls, large strings, or stream objects. You can refer to this type in the %Set() section.
USER>Set da = ##class(%DynamicArray).%New()

USER>Do da.%Push("test")

USER>Do da.%Push("","null")

USER>Do da.%Push(1,"Boolean")

USER>Do da.%Push("Test","string>Base64")

USER>Do da.%ToJSON()

["test",null,true,"VGVzdA=="]

%Remove(Key)

The %Remove method is used to delete an element from a JSON object or array. It returns the value of the removed element.

  • When working with objects, pass the key to the element to remove.
  • When working with arrays, pass the index of the element to remove.

Object

USER>Set json = {"username":"Test", "role":"Admin"} 
USER>Write json.%Remove("username")
Test
USER>Write json.%ToJSON()
json={"role":"Admin"} 

Array

USER>Set array = [1,2,3,4,5]
USER>Write array.%Remove(2)
3
USER>Write array.%ToJSON()
array=[1,2,4,5] 

Embedded Python

Embedded Python - remove(key)

The Python remove function deletes the specified key from a DynamicObject or removes the element at the given index from a DynamicArray.

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{

ClassMethod DAOremovePY(dao, key) [ Language = python ]
{
    dao._Remove(key) #invoke IRIS DynamicObject %Remove method 
    dao.remove(key)  #native Python method
}

ClassMethod DAORemove()
{
    Set json = ##class(%DynamicObject).%New()
    Set json."m_username"=$USERNAME
    Set json.roles=$ROLES
    Do ..DAOremovePY(json,"m_username")
    ZWrite json
    
    Set array = [1,"test",2,"test2"]
    Do ..DAOremovePY(array,2)
    ZWrite array
}
ClassMethod Sample2() [ Language = python ]
{
    da = iris.cls("%Library.DynamicArray")._New()
	da.put(0,3)
	da.put(1,4)
	da.remove(1)
	da.remove(2)
	print(da.size())
}

}

 

Output
USER>DO ##CLASS(Sample.DAO.EmpeddedPY). DAORemove()
json={"roles":"All"}  ; <DYNAMIC OBJECT>
array=[1,"test","test2"]  ; <DYNAMIC ARRAY>

 

This method is helpful when you need to clean up or selectively modify JSON structures during processing.

%Size()

The %Size() method returns the number of elements contained within a JSON object or array.

USER>Set json ={"username":($USERNAME),"role":($ROLES)}
USER>Write json.%Size()
2
USER>Set array = [1,2,3,4,5,6,7,9,0,121,"test"]
USER>Write array.%Size()
11

Embedded Python - size()

The Python size function returns the number of elements in a DynamicObject or DynamicArray

ClassMethod Size() [ Language = python ]
{
    import iris
    dao = iris.cls("%Library.DynamicObject")._New()
    #
    dao1 = iris.cls("%Library.DynamicObject")._New()
    dao1._Set("key1","AAA")
    dao1._Set("key2","AAA")
    #
    dao._Set("key1",dao1)
    dao._Set("key2",dao1)
    dao.put("key3",111)
    dao.put("key4","test")
    #Native Python size() function
    print(dao.size()) # output 4
    #IRIS DynamicArray %Size() method
    print(dao.get("key1")._Size()) # output 2 
}

The remaining methods will be discussed in the following article.

4 条新评论
讨论 (4)3
登录或注册以继续
文章
· 18 hr 前 阅读大约需 5 分钟

Dental Zirconia Cap: A New Era for Your Long Lasting Smile

Are you concerned about the health of your teeth and smile? Perhaps you are looking for a dental crown to strengthen a tooth after a broken tooth, major decay, or a root canal. In today’s times, dental technology has advanced so much that you have the best options available to you, and one of them is the dental cap zirconia crown. But why has this particular type of dental crown become the first choice of patients? Let us understand it in detail.

What is a Dental Cap Zirconia Crown and Why is it Special?

A zirconia crown, often referred to as a zirconium dental crown or simply a zirconia crown, is made of an extremely strong and white ceramic material called zirconium dioxide. This is the same material that is often used in medical implants, which is a testament to its biocompatibility (easily accepted by the body) and safety.

In the past, dental crowns were usually made of metal (such as gold, silver) or porcelain fused to metal (PFM). PFM crowns were good, but they had some aesthetic and biological disadvantages due to their metal base. Zirconia crowns have emerged as an excellent alternative by eliminating all these disadvantages.

Key Benefits of Zirconia Dental Crowns: Why Do Patients Prefer Them?

Zirconia crowns have many advantages that make them popular with both patients and dentists. Let’s take a look at the key benefits:

1. Unmatched Strength & Durability

Zirconia is known for its incredible strength. It is so strong that it can easily withstand the pressure of chewing in your mouth. This means that your zirconium dental crown is much less likely to break or crack. Especially for back teeth, where chewing pressure is at its highest, zirconia is an ideal choice. This strength allows it to last longer, saving you the expense and hassle of frequent replacements.

2. Natural Appearance and Aesthetics

This is perhaps the biggest advantage of zirconia. Zirconia closely matches the color, translucency, and light reflection of natural teeth. Its white, opaque color allows it to blend in with natural teeth, making it virtually indistinguishable. Since traditional PFM crowns have a metal base, a dark line could appear at the gum line over time. Since zirconia has no such metal, your smile looks completely natural and beautiful. After a zirconia dental cap is placed, no one will know that it is not your natural tooth.

3. Excellent Biocompatibility

Zirconium dioxide is a biocompatible material. This means that it is easily accepted by the body and is very unlikely to cause allergic reactions or tissue irritation. For patients with metal allergies, zirconia crowns are a safe and superior option. They are also very friendly to gum tissue, making the gum line look healthy and natural.

4. Metal-Free & Allergy-Free

In the modern era, many people are sensitive to the use of metal or prefer metal-free alternatives. Zirconium dental crowns are completely metal-free. This is not only an aesthetic advantage (lack of a dark gum line), but it is also ideal for patients with metal allergies or sensitivities.

5. Precise Fit & Comfort

Zirconia crowns are manufactured using state-of-the-art CAD/CAM (Computer-Aided Design / Computer-Aided Manufacturing) technology. This technology helps in creating crowns with utmost precision, which fit perfectly on your teeth. This precise fit ensures comfort and reduces the chances of food particles or bacteria getting trapped under the crown, which is beneficial for dental health in the long run.

6. Less Tooth Reduction

In some cases, less tooth structure needs to be removed for a zirconia crown. This means that more of your natural tooth is preserved, which is always better for dental health.

In which cases is a dental crown zirconia the best choice?

Zirconia dental caps can be used for a variety of dental problems, including:

  • Badly damaged teeth: When a tooth is severely decayed, broken, or has a large crack.
  • After root canal treatment: After a root canal, a tooth is weakened, requiring a crown to strengthen it.
  • As part of a bridge to replace a missing tooth: Zirconia bridges provide a strong and aesthetic solution to replace a missing tooth.
  • Crown on dental implants: A crown placed on an implant should be strong and natural-looking, where zirconia excels.
  • Smile correction: For aesthetic correction if the shape, size, or color of a tooth is not right.

Zirconia Crown Procedure: What to Expect?

The process of fabricating a zirconia crown is usually completed in two visits:

First Visit: Your dentist will examine your tooth and prepare it for the crown. This includes removing any decay and shaping the tooth to fit the crown. Then, measurements are taken of the tooth, which are sent to a dental laboratory. Modern laboratories use digital scanning technology, which makes the measurements more accurate. You may also be fitted with a temporary crown.

Second Visit: Once your custom-made zirconia dental crown is ready from the laboratory, the dentist will fit it onto your tooth to check its fit and bite. Once everything is in order, the crown is permanently cemented onto the tooth.

Zirconia Crown Cost: Is It Worth the Investment?

Zirconia dental caps may cost slightly more than other crowns (such as PFM). However, due to their unparalleled strength, long life, and natural aesthetic appearance, they prove to be an excellent investment in the long run. Since the crown does not need to be replaced frequently, they can also be cost-effective. The price depends on factors such as the dental clinic, the experience of the dentist, the city, and the quality of the dental laboratory.

How to care for a zirconia crown?

Caring for a zirconia crown is as easy as caring for your natural teeth:

Regular brushing and flossing: Brush twice a day and floss regularly.

Dental check-ups: Visit your dentist regularly (every six months) to have your crown and overall oral health checked.

Avoid chewing hard objects: Avoid chewing very hard objects like ice, pencils, although zirconia is strong, the extra pressure can cause damage.

Avoid Bruxism: If you have a habit of grinding your teeth at night, talk to your dentist. They may recommend a night guard.

With this proper care, your zirconium dental crown can last for many years.

Conclusion: Zirconia - The Future of Smiles

Zirconia dental caps are a revolutionary advancement in modern dentistry. Its exceptional strength, natural appearance, excellent biocompatibility and long life make it the first choice for patients. If you are considering restoring your smile or strengthening a damaged tooth, it would definitely be beneficial to discuss a zirconia crown with your dentist. It will help you regain a confident, beautiful, and functional smile, which will significantly improve your quality of life.

Remember, choosing a quality dental crown is an investment in the long-term health of your teeth. A zirconium dental crown made by the right dental laboratory can provide you with years of trouble-free smiles.

讨论 (0)1
登录或注册以继续
文章
· 22 hr 前 阅读大约需 3 分钟

Sin límites locales: exponiendo InterSystems IRIS con ngrok

En los hackatones en los que participó InterSystems y en los que dimos soporte, muchos estudiantes preguntaban cómo podían hacer para que todos los miembros de su equipo usaran la misma base de datos IRIS que habían levantado en un contenedor. Sugerí usar ngrok para exponer su instancia local de IRIS y me di cuenta de que no tenemos documentación al respecto. Por eso pensé que sería una gran idea dar a conocer esta técnica tan útil para mejorar la colaboración durante el desarrollo y las pruebas.

1 条新评论
讨论 (1)2
登录或注册以继续