Hi Lucas,

A simple solution to you question can be this :

Property numDossiersMER As list Of %Integer(SQLPROJECTION = "table/column", STORAGEDEFAULT = "array");

Index numDossiersMERIdx On numDossiersMER(ELEMENTS);

With those parameters you can achieve :

  • 'As list Of %Integer' allows you to use the Insert() in ObjectScript and 'for some %element' in SQL command
  • 'SQLPROJECTION = "table/column"' allows you to display the table as a column (note, the column does not appear in a select * it must be specified : select numDossierMER, numDossiersMER from User_TestList_Data.Titre )
  • 'STORAGEDEFAULT = "array"' allows a separate table for the normalized representation
  • 'Index numDossiersMERIdx On numDossiersMER(ELEMENTS);' bring the ability to use index on values with this SQL query :
select numDossierMER, numDossiersMER from User_TestList_Data.Titre
where
for some %element(numDossiersMER) (%Value in (345))

Hi Cindy,

To deploy your services, routes and plugins to another environment you can use CI/CD with postman (newman)

Some examples here :

Another possibility is to use deck (decK helps manage Kong’s configuration in a declarative fashion) from kong

I haven't tried this one, I can't give you feedback on it.

I tried your module as a replacement for the Manifest installer, see this example:

https://github.com/grongierisc/intersystems-iris-dev-template

However, I'm stuck for the part with ZPM.
The problem is, with your module, I can create a database, its rights, etc., but how to tell ZPM to load the classes in the freshly installed NameSpace?


What are the possible solutions?

We have today many options to load configuration IRIS, are they in competition?

How to federate these modules who are all complementary?

If I understand correctly, you want to replace an HTTP Header basic auth with a bearer token.
If the bearer token is static, you can implement a solution like this:
- https://github.com/grongierisc/iam-training/tree/training#6-third-add-ou...

If it is dynamic, I think you will have to develop your own plug-in:
- https://github.com/grongierisc/iam-training/tree/training#11-plugins

A good base to start working on could be this plugin:
- https://github.com/grongierisc/kong-plugin-jwt-crafter

Hi Yeung,

First how-to auto increment an integer, you can use this property :

Then, why you have ID1 in your table, because by default any persistent class have an column called ID who is an auto increment and indexed as a primary key.
You can overload this primary key by your own with this index :

Hi,

What you can do is a snapshot of this ResultSet.

Then use the global of this snapshot for another Operation :

Get snapshot global :

Method OnGetSnapshot(pRequest As Ens.Request, Output pResponse As Ens.StringResponse) As %Status
{
    set tStatus = $$$OK

    try{

        set pResponse = ##class(Ens.StringResponse).%New()

        set tQuery = "SELECT *  FROM [sqlserver].[dbo].[whatever] "

        //$$$TRACE(tQuery)      
        Set pSnap = ##class(EnsLib.SQL.Snapshot).%New()

        //size of snapshot
        // -1 = Max
        set pSnap.MaxRowsToGet = -1

        $$$ThrowOnError(..Adapter.ExecuteQueryBatch(pSnap,tQuery,1000))

        $$$ThrowOnError(pSnap.%Save())


        set pResponse.StringValue = pSnap.%GblRef   

    }
    catch exp
        {
            Set tStatus = exp.AsStatus()
        }
    Quit tStatus
}

Use snapshot global :

Method UseSnapshot(pRequest As Ens.StringRequest, Output pResponse As Ens.Response) As %Status
{

    set status = $$$OK

    try {
        set pResponse = ##class(Ens.Response).%New()

        set nRow = 0
        set tSequence = 0

        //Get SnapShot
        Set tSnap = ##class(EnsLib.SQL.Snapshot).%New()
        set tSnap.%GblRef = pRequest.StringValue // use of global SnapShot
        set tSnap.%CurrentRow = 0
        set tSnap.FirstRow = 1
        set tSnap.MaxRowsToGet = -1

        $$$TRACE("MaxRowsToGet :  "_tSnap.RowCountGet())

                while tSnap.Next() {
                    try {
                            set nRow = nRow + 1
                            set tSequence = tSequence + 1

                            set i = 0

                            set i = i + 1
                            set tParam(i) = tSnap.Get("Col1")


                            set i = i + 1
                            set tParam(i) = tSnap.Get("Col2")


                            set i = i + 1
                            set tParam(i) = tSnap.Get("Col3")


                            set i = i + 1
                            set tParam(i) = tSnap.Get("ColX")

                            set tParam = i

                            set tQuery = "UPDATE Whatever  "_
                                        "SET   "_
                                        "Col1 = ?  "_
                                        ",Col2 = ?  "_
                                        ",Col3 = ?  "_
                                        " WHERE ColX = ?  " 


                            $$$ThrowOnError(..Adapter.ExecuteUpdateParmArray(.tResult,tQuery,.tParam))

                        } catch exSnap {
                            // Update exeption
                        }

        }


    } catch ex {
        set status = ex.AsStatus()
    }
    return status
}

Furthermore, If you have big table to query/insert in JDBC consider this ZPM module :
https://github.com/grongierisc/BatchSqlOutboundAdapter

Hi Alexender, I'll send you the WSDL in PM.

But I guess I found a workaround :

I created a new method that parse the XML with %XML.Reader and correlate the payload with my destination class :

 set reader = ##class(%XML.Reader).%New()
 // pRequest.GetPatientsByClinicResult.any.GetAt(1) <-- Header
 // pRequest.GetPatientsByClinicResult.any.GetAt(2) <-- Payload
 do reader.OpenString(pRequest.GetPatientsByClinicResult.any.GetAt(2))
 do reader.Correlate("Patients","FME.Object.Patient")

 while reader.Next(.object,.status) {
   do pResponse.Patients.Insert(object)
 }

Where FME.Object.Patient is :

Class FME.Object.Patient Extends (%SerialObject, %XML.Adaptor)
{

Property LastName As %String;

Property FirstName As %String;

Property Datex0020ofx0020Birth As %String(XMLNAME = "Date_x0020_of_x0020_Birth");

Property Gender As %String;

Property Code As %String;

Property Insurance As %String;

Property GUID As %String;

Property CLINICGUID As %String;

}

Hi Mike,
To retrive multi-part from %resquest you have do to this in the %CSP.REST class :

    // Get properties
    set body = %request.Get("body")
    if '$d(body) {
      $$$ThrowOnError($$$ERROR(9200,"no parameters"))
    }
    set dynaBody = {}.%FromJSON(body)

    // Get stream
    set stream = %request.GetMimeData("file")
    if ('$IsObject(stream) {
      $$$ThrowOnError($$$ERROR(9200,"no file"))
    }

To get property you have to use Get and for stream GetMimeData
In my example my body is a json.

Hi Yuri,
Have a look at this : https://github.com/grongierisc/iris-csvgen-ui/blob/master/src/CSVGEN/API...
Here you will find and example of a multi-part upload on a %CSP.REST class.

To get the stream from the multi part you have to do this ligne 39 to 43 :

    // Get stream
    set stream = %request.GetMimeData("id")
    if ('$IsObject(stream) {
      $$$ThrowOnError($$$ERROR(9200,"no file"))
    }

Where id is the name of you multi-part

To send the stream to a business service :

        $$$ThrowOnError(##class(Ens.Director).CreateBusinessService(BsName,.tService))

        $$$ThrowOnError(tService.ProcessInput(stream,.output))

Where BsName is the name of your business service in the active production of your namespace.
And stream you stream.