Pesquisar

Artigo
· Out. 19 6min de leitura

IKO Plus: Multi-Cluster IrisClusters Propogated with Karmada

Kamino for IrisClusters

If you are in the business of building a robust High Availability, Disaster Recovery or Stamping multiple environments rapidly and in a consistent manner Karmada may just be the engine powering your Cloning Facility.



I lost the clone war with KubeAdmiral but won the pod race with Karmada and would like to pay it forward with what I figured out.   This is a mult-cluster solution, that I would consider to be a day zero with day one management of Kubernetes objects, IrisCluster included.


To keep inline with Cloud Native Computing Foundation standards, the Star Wars analogy is required, so here it goes.




Boba Fett's genetics were sent and prepared on Kamino, which triggered numberous clones were subsequently deployed across the galaxy.  Some went to Endor, some went to Tatooine, others got deployed on the Death Star, and some even defected and bought a Ford F-150 and moved to Montana.  But in all cases, the Clone essentially evolved on its own, but retained the base genetic footprint.  This is somewhat the idea for Karmada, deploying resources to meet HA/DR, stretched, or purposeful environments with a single decleration of what the IRis

If you are looking for a more plausible use case for understanding Karmada, or generally fell out of favor of Disney's acquisition of the Star Wars franchise, here is one to take to a meeting, Multi-Cluster Secrets Management.

So if you are a Kubehead (tm) and tend to do this on the regular to sync secrets across clusters...

kubectl --context source get secret shhhh-secret -o yaml | kubectl --context target apply -f -

You may want to look a this from just that angle as a simple, yet powerful backdrop.

Goal

Lets provision a pair of clusters, configure Karmada on one of them and join the second one to the Karmada control plane for the PUSH model.  Once the second cluster is joined, we are going to provision an IrisCluster on the Karmada control plane, and propogate it to the member cluster.

Then, lets had a third cluster to Karmada and deploy the same IrisCluster to that one.



Clusters

Create a pair of clusters in Kind, one named Fett and the other Clone, this sill also install the Cilium CNI:

 

cat <<EOF | kind create cluster --name ikofett --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
networking:
  disableDefaultCNI: true
EOF

cat <<EOF | kind create cluster --name ikoclone --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
networking:
  disableDefaultCNI: true
EOF

kind get kubeconfig --name ikoclone > ikoclone.kubeconfig
kind get kubeconfig --name ikofett > ikofett.kubeconfig

KUBECONFIGS=("ikoclone.kubeconfig" "ikofett.kubeconfig")

for cfg in "${KUBECONFIGS[@]}"; do
  echo ">>> Running against kubeconfig: $cfg"
  cilium install --version v1.18.0 --kubeconfig "$cfg"
  cilium status --wait --kubeconfig "$cfg"
  echo ">>> Finished $cfg"
  echo
done


You should now have a pair of clusters and a pair of kubeconfigs.


IKO

IrisCluster is a CRD and IKO efficiently creates them, its important to ensure that IKO exists along with the CRDS on all clusters.
 

KUBECONFIGS=("ikoclone.kubeconfig" "ikofett.kubeconfig")

for cfg in "${KUBECONFIGS[@]}"; do
  echo ">>> Running against kubeconfig: $cfg"
  helm install iko iris-operator/ -f iris-operator/values.yaml --kubeconfig "$cfg"  
  echo ">>> Finished $cfg"
  echo
done

Now, from a previous post we just so happen to have a stretched cluster laying around, so we will use that towards the end.


Karmada

Installing Karmada via Helm Chart is the easiest route with a fresh Kind cluster, so lets do that on `ikofett`

helm repo add karmada-charts https://raw.githubusercontent.com/karmada-io/karmada/master/charts
helm repo update
helm --namespace karmada-system upgrade -i karmada karmada-charts/karmada --version=1.15 --create-namespace --kubeconfig ikofett.kubeconfig


❗ The next step is pretty important, and a cornerstone to understanding cluster interaction.

We now need to create the kubeconfig to interact with the karmada cluster api.

You should now have 3 kubeconfigs... you will be interacting with the newly generated one often.

Here is an illustration of cluster api interaction at this stage of the distraction:

 
❗Important Networking Using Kind

Now that we have the Karmada control plane setup, lets just install the IKO crds into it. Instead of installing the entire operator, just add the crds from another machine into that control plane.

kubectl --kubeconfig ikofett.kubeconfig get crd irisclusters.intersystems.com -o yaml > ikocrds.yaml
kubectl create -f ikocrds.yaml --kubeconfig ikokamino.kubeconfig


We should have Karmada ready for business, lets propogate an IrisCluster.

Join

Now we have to let Karmada know about and be able to "talk" to the member cluster, in our case, `ikoclone` of which we created in Kind.

sween @ fhirwatch-pop-os ~/Desktop/IKOPLUS/karmada
└─ $ ▶ kubectl karmada --kubeconfig ikokamino.kubeconfig  join ikoclone --cluster-kubeconfig=ikoclone.kubeconfig
cluster(ikoclone) is joined successfully



Propogate

Now we are going to do the two-step to deploy and propogate our IrisCluster, interacting only with the karmada api.

Step one

Deploy iriscluster to Karmada.  This does NOT deploy an actual workload, it simply stores the definition, much like a "template" for an IrisCluster, or if we are still tracking to the Star Wars analagy, the DNA of the clone.

# full IKO documentation:
# https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_deployment_iko
apiVersion: intersystems.com/v1alpha1
kind: IrisCluster
metadata:
  name: federated-iris
spec:
  topology:
    data:
      image: containers.intersystems.com/intersystems/iris-community:2025.1
  serviceTemplate:
    spec:
      type: LoadBalancer
      externalTrafficPolicy: Local

 

You can query irisclusters in the karmada control plane, but you will notice its basically just a stub.



Step two

Deploy a propogation policy to send it.

apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
  name: iriscluster-propagate
  namespace: default
spec:
  resourceSelectors:
  - apiVersion: intersystems.com/v1alpha1
    kind: IrisCluster
  placement:
    clusterAffinity:
      clusterNames:
      - ikoclone    #### our clone or member cluster

On the clone you should see a spun up IrisCluster!

Join Another and Propogate Another

Revisit the additional kubeconfig for brevity.

Now in one full swoop, lets join a stretched cluster out on Google Cloud Platform from a previous post with a similar join.

 
The second cluster is now available for business out in Google Cloud Platform as a Stretched Cluster.


To get a IrisCluster out there, we just have to edit our propogation policy to include the new target `k8s`.

And there you have it, another clone of the IrisCluster out on GCP

This scratches the surface with Karmada, check the docs for professional flexibility with your clones:
 

  • overrides on resources per joined cluster
  • networking integration with submariner
  • governance guidance
  • PUSH configuration, a lot like ArgoCD (PULL was above)
  • ...
  • ...

1 novo comentário
Discussão (1)2
Entre ou crie uma conta para continuar
Artigo
· Out. 19 14min de leitura

Uma Interface Web e Classe Reutilizáveis para Manutenção de Tabelas de Pesquisa (Lookup Tables) de Dados no HealthConnect

Visão Geral

Esta interface web foi projetada para facilitar o gerenciamento de Tabelas de Pesquisa de Dados (Data Lookup Tables) por meio de uma página web amigável. É particularmente útil quando os valores da sua tabela de pesquisa são grandes, dinâmicos e mudam frequentemente. Ao conceder aos usuários finais acesso controlado a esta interface web (permissões de leitura, escrita e exclusão limitadas a esta página), eles podem gerenciar os dados da tabela de pesquisa de forma eficiente, de acordo com suas necessidades.

Os dados gerenciados por meio desta interface podem ser utilizados perfeitamente em regras ou transformações de dados do HealthConnect, eliminando a necessidade de constante monitoramento e gerenciamento manual das tabelas de pesquisa, economizando tempo significativo.

Nota: 

Se a Tabela de Pesquisa de Dados padrão não atender aos seus requisitos de mapeamento, você pode criar uma tabela personalizada e adaptar esta interface web, juntamente com sua classe de suporte, com modificações mínimas. O código de exemplo da classe está disponível mediante solicitação.

Pré-requisitos

Antes de usar a interface web, certifique-se de ter criado uma Lookup Table de Dados vazia no HealthConnect:

  1. Navegue até Interoperabilidade → Configurar → Data Lookup Tables.
  2. Clique em Novo para abrir o pop-up "Create New Lookup Table".
  3. Insira o nome desejado para sua tabela de pesquisa e clique em OK
  4. Clique em Salvar para finalizar a criação da tabela
  5. Verifique a criação da tabela de pesquisa clicando em Abrir na mesma janela — sua nova tabela deve aparecer na lista.

Nesta documentação, o nome da Tabela de Pesquisa de Dados de exemplo usado é:
"Example of data lookup table"

Instruções de Uso

O processo de configuração é simples:

  1. Obtenha o código:  Baixe o código fornecido no repositório GitHub ou copie-o do link da comunidade.
  2. Crie uma página CSP:  Crie uma nova página CSP em seu ambiente HealthConnect e cole o código completo do arquivo DataLookupWebApp.
  3. Crie uma classe:  Copie e cole o código da classe fornecido na documentação ou no repositório

Configuração

Antes de compilar e executar:

  1. Coloque o nome da sua Tabela de Pesquisa de Dados na página web, substituindo o placeholder indicado pela caixa vermelha na captura de tela abaixo pelo nome real da sua tabela de pesquisa.

 

  1. Certifique-se de que o nome da classe no código corresponda ao nome da sua classe personalizada.

  1. Atribua o nome da sua tabela de pesquisa na classe, onde indicado por myDtName = 'your data lookup table'. Veja a captura de tela acima.

 

  1. Compile tanto a classe quanto a página CSP para finalizar a configuração.

 

Testando a Aplicação

Adicionar Registros

  • Insira a chave e o par chave-valor correspondente nos campos do formulário.
  • Clique em Add Record (Adicionar Registro) para inserir os dados na tabela de pesquisa.

Captura de tela 1: Adicionando Registros (122 – Spine X-ray)

Atualizar Registros

  • Selecione um registro existente e modifique o par chave-valor conforme necessário.

 

  • Clique em Update (Atualizar) para salvar as alterações.  Exemplo: Atualizando 122 "Spine X-ray" para "Abdominal X-ray (AXR)".

Excluir Registros

  • Selecione o registro a ser excluído (144 – MRI).

  • Clique no botão Delete (Excluir) para remover o registro da tabela de pesquisa. Exemplo: Excluindo "144 - MRI".

Verificar Tabela de Pesquisa de Dados no HealthConnect

Navegue até Interoperabilidade → Configurar → Data Lookup Tables → Abrir

 

Pesquisar Registro

Código / Recursos

  • O código fonte completo também está disponível no GitHub para download e referência:

https://github.com/pandeySR/Reusable-Web-Interface-for-Data-Lookup-Table

 

<!DOCTYPE html>
<!--
This web application is designed and developed to insert, update, and delete records (key–value pairs) in the Data Lookup Table through a web interface.
Author: Sanjib Pandey
Date: 16/10/2025
-->
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="author" content="Sanjib Pandey" />
  <title>YOUR TITLE : Data Lookup Table - Data Record </title>
  <!-- Bootstrap CSS CDN, jQuery, Datatable -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> 
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> 
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="https://cdn.datatables.net/1.13.5/css/dataTables.bootstrap5.min.css" />
  <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
  <script src="https://cdn.datatables.net/1.13.5/js/jquery.dataTables.min.js"></script>
  <script src="https://cdn.datatables.net/1.13.5/js/dataTables.bootstrap5.min.js"></script>
  <style>
    h2 {
      text-align: center;
      color: #fff;
      background-color: #00b300;
      padding: 15px 10px;
      border-radius: 5px;
      margin-bottom: 5px;
      margin-top: 0px;
    }
    html, body {
      height: 100%;
      margin: 0;
    }
    body {
      display: flex;
      min-height: 100vh;
      background-color: #f8f9fa;
      padding-top: 10px;
      flex-direction: column;
      align-items: center;
    }
    .container {
      max-width: 1100px;
      background: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 0 15px rgba(0,0,0,0.2);
      margin-top: 5px;
      width: 100%;
    }
 
    .table-scroll-vertical
    {
 	 max-height: 450px;
 	 overflow-y: auto;
  	 border: 1px solid #dee2e6;
  	 border-radius: 5px;
  	 margin-top: 0; 
	}
	
	.small-italic 
	{
  	 font-size: 0.85em; 
  	 font-style: italic; 
  	 color: #C0C0C0; 
	}
	
	.dataTables_filter label 
	{
  	 font-weight: bold;
  	 color: #333;
  	 color: red;
  	 float: left;
	}

	.dataTables_filter input
	{
  	 border: 2px solid #993399;
  	 border-radius: 5px;
  	 padding: 6px 10px;
  	 outline: none;
   	 width: 250px;
	}
	
	.page-footer
	{
  	 text-align: center;
  	 padding: 10px 5px;
  	 font-size: 0.95rem;
 	 color: #809fff;
 	 background-color: #f8f9fa;
  	 border-top: 1px solid #993399;
  	 margin-top: 5px;
	}
  </style>
  <style>
  @keyframes blink
  {
    50%
    {
      opacity: 0;
    }
  }
</style>
</head>
<body>
<div class="container">
<div style="overflow: hidden;">
  <div style="float: left; font-size: smaller; font-weight: bold;color:#b3ffff;animation: blink 1s infinite;">
    Environment : DEV
  </div>
  <h2 style="text-align: center; margin: 0;">
    Your Organization Name or Company Name<br>
    <span style="font-size: smaller; color: yellow;text-align: center;">Data Lookup Table</span>
  </h2>
</div> 
 <form id="recordForm" class="form-horizontal" action="" method="POST">
 	<div class="form-group">
        <!--for any other information if you want> -->
       </div>
      <div class="row mb-3">
        <label for="key" class="col-sm-3 col-form-label fw-bold">Key :</label>
        <div class="col-sm-9">
          <input type="text" class="form-control" id="key" name="key" placeholder="Enter the Key data !" required />
        </div>
      </div>
      <div class="row mb-3">
        <label for="kvalue" class="col-sm-3 col-form-label fw-bold">Key Pair Value</label>
        <div class="col-sm-9">
          <input type="text" class="form-control" id="kvalue" name="kvalue" placeholder="Enter the key paris value !" required />
        </div>
      </div>
	<div class="d-flex justify-content-between align-items-center mt-4 flex-wrap">
		<p class="mb-2 mb-md-0 text-primary">
    		<i>Click the edit icon to modify a record, then press "Update" to save. To delete, press the "Delete" button.</i> 
  		</p> 
  		
	<div class="d-flex flex-wrap justify-content-end">
		<button class="btn btn-success me-2" id="Add" type="submit" name="Add">
			<i class="fa fa-plus me-1" style="font-size:18px; color:white;"></i> Add Record
		</button>
	
		<button class="btn btn-primary me-2" type="submit" name="Update">
			<i class="fa fa-edit me-1" style="font-size:18px;"></i> Update
    	</button>

		<button class="btn btn-danger me-2" id="Delete" type="submit" name="Delete">
			<i class="fa fa-remove me-1" style="font-size:18px;"></i> Delete
		</button>
		
		<button class="btn btn-info" id="Cancel" type="submit" name="Cancel">
  			<i class="glyphicon glyphicon-refresh" style="font-size:18px;"></i> Cancel
		</button>
  	   </div> 
    </div>
    <div></div>
	</form>
<script language=SQL name="query">
  SELECT KeyName, DataValue FROM Ens_Util.LookupTable WHERE TableName='Data Lookup Table Example'
</script>

<script language=cache runat=server>
 S myKeyName=$Get(%request.Data("key",1))
 S myKeyValue=$Get(%request.Data("kvalue",1))
 S myDtName="Data Lookup Table Example"
 I ($Data(%request.Data("Add",1)))
 {
	I ((myKeyName '="") && (myKeyValue '="") && (myDtName '=""))
	{	
		I ##Class(SANJIB.DataLookup.Methods).ChkLookupKeyValue(myDtName,myKeyName)="F"
		{
			D ##Class(SANJIB.DataLookup.Methods).InsertLookUpValues(myDtName,myKeyName,myKeyValue)
		}
		else
		{	W "The key has already been inserted.." &html<<div style=color:red>#(myKeyName)#</div>> }
		
	}
 }
 I ($Data(%request.Data("Update",1)))
 {
	I ((myKeyName '="") && (myKeyValue '="") && (myDtName '=""))
	{
		D ##Class(SANJIB.DataLookup.Methods).UpdateLookUpValues(myDtName,myKeyName,myKeyValue)
	}
 }
 I ($Data(%request.Data("Delete",1)))
 {
	 I ((myKeyName '="") && (myKeyValue '="") && (myDtName '=""))
	 {
		D ##Class(SANJIB.DataLookup.Methods).DeleteLookUpValues(myDtName,myKeyName)		
	 }
 }	
</script>
 <div class="table-responsive table-scroll-vertical"> 
    <table class="table table-bordered border-primary table table-hover mt-2" id="dataTable" style="min-width: 1000px;">
      <thead class="table-warning">
        <tr>
          <th>Key Data</th>
          <th>Key Pair Value</th>
          <th style="text-align:center;">Actions</th> 
        </tr>
      </thead>
      <tbody id="tableRecordset">
 		</tr>
 		<csp:while counter=myQueryRow condition=query.Next()>
 			<tr class='#($S(myQueryRow#2:"LightRow",1:"LightRow"))#'>
  				<csp:while counter=myQueryColumn condition="(myQueryColumn<query.GetColumnCount())">
      				<td style="background-color:#e6ffff">#(query.GetData(myQueryColumn))#</td>
  						</csp:while>
 							<td style="text-align:center;">
          						<button class="btn btn-sm btn-danger me-2 edit-delete-btn" data-id="#(query.GetData(0))#">
    								<i class="fa fa-edit"></i>
    								<i class="fa fa-trash"></i>
  								</button>
        					</td> 
 						</tr>
 				</csp:while>
      		</tbody>
       </table>
    </div>
  </div>
  
<script language=javascript>
  document.addEventListener('DOMContentLoaded', () => 
  {
    const editButtons = document.querySelectorAll('.edit-delete-btn');
    editButtons.forEach(button =>
    {
      button.addEventListener('click', () => 
      {
        const row = button.closest('tr');
        document.getElementById("Add").disabled=true
        const kID=row.cells[0].textContent.trim();
        const pairVal = row.cells[1].textContent.trim();
        document.getElementById('key').value = kID;
        document.getElementById('kvalue').value = pairVal;
        document.getElementById('key').focus();
      });
    });
  });
</script>
 <script language=javascript>
    document.getElementById('Cancel').addEventListener('click', () => 
    {
    	event.preventDefault();
    	document.getElementById('recordForm').reset();
    });
</script>

<script language=javascript>
  $(document).ready(function()
  {
    $('#dataTable').DataTable(
    {
      "order": [[0, "asc"]],
      "paging": true,
      "lengthChange": false,
      "searching": true,
      "info": true,
      "autoWidth": false
    });
  		$('#dataTable_filter input').css('font-size', '12px').attr('placeholder', 'Type to search..?');
  });
</script>

</body> 

<script language="javascript">
  document.addEventListener('DOMContentLoaded', () =>
  {
  	const updateBtn = document.querySelector('button[name="Update"]');
  	const deleteBtn = document.querySelector('button[name="Delete"]');
  	const addBtn = document.getElementById('Add');
  	const cancelBtn = document.getElementById('Cancel');
  	updateBtn.style.display = 'none';
  	deleteBtn.style.display = 'none';
  	addBtn.style.visibility = 'visible';  
  	addBtn.disabled = false;
  document.querySelectorAll('.edit-delete-btn').forEach(editBtn =>
  {
    editBtn.addEventListener('click', () =>
    {
      updateBtn.style.display = 'inline-block';
      deleteBtn.style.display = 'inline-block';
      addBtn.style.display = 'none';
      addBtn.style.visibility = 'visible'; 
      addBtn.disabled = true;
    });
  });
  updateBtn.addEventListener('click', (e) =>
  {
    updateBtn.style.display = 'none';
    deleteBtn.style.display = 'none';
    addBtn.style.display = 'inline-block';
    addBtn.style.visibility = 'visible';
    addBtn.disabled = false;
  });
  deleteBtn.addEventListener('click', (e) =>
  {
    updateBtn.style.display = 'none';
    deleteBtn.style.display = 'none';
    addBtn.style.display = 'inline-block';
    addBtn.style.visibility = 'visible';
    addBtn.disabled = false;
  });
  cancelBtn.addEventListener('click', (e) =>
  {
    e.preventDefault();  
    document.getElementById('recordForm').reset();
    updateBtn.style.display = 'none';
    deleteBtn.style.display = 'none';
    addBtn.style.display = 'inline-block';
    addBtn.style.visibility = 'visible';  
    addBtn.disabled = false;              
  });
});
</script>

<footer class="page-footer">
  <a href="https://sanjibpandey.wixsite.com/pandey/" target="_blank" rel="noopener noreferrer" style="color: #6c757d; text-decoration: none;"> https://sanjibpandey.wixsite.com/pandey/</a>
</footer>
</html>

 

/// Essa classe serve para inserir, atualizar e deletar registros (chave & valor)
/// em Lookup Tables desde uma aplicação web
/// Posteriormente, pode ser usada em regras ou transformações de dados usando a função de Lookup.
/// Autor : Sanjib Pandey
/// Data : 16/10/2025
Class SANJIB.DataLookup.Methods Extends %Persistent
{

/// Esse método insere um valor na Lookup Table. Os parâmetros requeridos são
/// dtTableName : O nome da sua lookup table
/// keyData     : A chave
/// keyValue    : O valor (par chave-valor)	
ClassMethod InsertLookUpValues(dtTable As %String = "", keyData As %String = "", keyValue As %String = "") As %Status
{
    S tSC = $$$OK
    Try
    {
        I (dtTable '="") && (keyData '="") && (keyValue '="")
        {
            S mySQLStatement = "INSERT into Ens_Util.LookupTable (KeyName,DataValue,TableName) values ('"_keyData_"','"_keyValue_"','"_dtTable_"')"
            S myRecordSet = ##class(%SQL.Statement).%ExecDirect(,mySQLStatement)
            S tSC={"InserRecorded":(myRecordSet)}
        }
    }
    Catch (Exception)
    {
        Throw Exception	
    }
    Q tSC
}

/// Esse método checa se o valor já existe na lookup table
ClassMethod ChkLookupKeyValue(dtTable As %String, keyData As %String) As %Status
{
    S tSC = $$$OK
    Try
    {
        I (dtTable '="") && (keyData '="")
        {
            S mySQLStatement="SELECT KeyName FROM Ens_Util.LookupTable WHERE TableName='"_dtTable_"' and KeyName='"_keyData_"'"
            S myRecordSet = ##class(%SQL.Statement).%ExecDirect(,mySQLStatement)
            D myRecordSet.%Next()
            I (myRecordSet.%SQLCODE=0)
            { 
                S tSC= "T"
            }
            else
            {
                S tSC="F"
            }
        }
        else
        {
            S tSC= "Invalid Parameters - missing table name or key !"
        }
    }
    Catch (Exception)
    {
        Throw Exception	
    }
    Q tSC
}

/// Esse métood atualiza somente o valor chave na lookup table.
ClassMethod UpdateLookUpValues(dtTable As %String = "", keyData As %String = "", keyValue As %String = "") As %Status
{
    S tSC = $$$OK
    Try
    {
        I (dtTable '="") && (keyData '="") && (keyValue '="")
        {
            S mySQLStatement = "UPDATE Ens_Util.LookupTable SET DataValue='"_keyValue_"' WHERE TableName='"_dtTable_"' AND KeyName='"_keyData_"'"
            S myRecordSet = ##class(%SQL.Statement).%ExecDirect(,mySQLStatement)
            S tSC={"Updated Record":(myRecordSet)}
        }
    }
    Catch (Exception)
    {
        Throw Exception	
    }
    Q tSC
}

/// Esse método é usado para deletar um registro da lookup table.
ClassMethod DeleteLookUpValues(dtTable As %String, keyData As %String) As %Status
{
    S tSC = $$$OK
    Try
    {
        I (dtTable '="") && (keyData '="") 
        {
            S mySQLStatement = "DELETE FROM Ens_Util.LookupTable WHERE  TableName='"_dtTable_"' And KeyName='"_keyData_"'"
            S myRecordSet = ##class(%SQL.Statement).%ExecDirect(,mySQLStatement)
            S tSC={"Deleted Record":(myRecordSet)}
        }
    }
    Catch (Exception)
    {
        Throw Exception	
    }
    Q tSC
}

Storage Default
{
<Data name="MethodsDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
</Data>
<DataLocation>^SANJIB.DataLookup.MethodsD</DataLocation>
<DefaultData>MethodsDefaultData</DefaultData>
<IdLocation>^SANJIB.DataLookup.MethodsD</IdLocation>
<IndexLocation>^SANJIB.DataLookup.MethodsI</IndexLocation>
<StreamLocation>^SANJIB.DataLookup.MethodsS</StreamLocation>
<Type>%Storage.Persistent</Type>
}

}

Conclusão

Esta interface web e classe reutilizáveis fornecem uma maneira simples, porém eficaz, de gerenciar Tabelas de Pesquisa de Dados no HealthConnect, aumentando a eficiência e a flexibilidade. Ao capacitar os usuários finais com acesso controlado, ela reduz a sobrecarga administrativa tradicionalmente associada à manutenção da tabela de pesquisa.

Discussão (0)1
Entre ou crie uma conta para continuar
Job
· Out. 19

MP Breaking News: Stay Updated with the Latest from Madhya Pradesh

For the most timely and reliable updates, MP Breaking News from Dainik Jagran MP CG is your trusted source for everything happening across Madhya Pradesh. The portal provides in-depth coverage of politics, governance, social issues, economy, culture, and weather, ensuring citizens remain connected to the most important state developments.

Recently, Chief Minister Dr. Mohan Yadav has been actively visiting flood-affected regions such as Ujjain and Satna. Relentless efforts are made, and over ₹193 crore has been disbursed directly to farmers, reflecting efficient governance. Moreover, Dhamtari district earned the prestigious President’s Award for outstanding implementation of the PM Janman Yojana, highlighting Madhya Pradesh’s dedication to innovative welfare practices.

Weather forecasts reveal Madhya Pradesh is witnessing cooler mornings and light rain showers, signaling the onset of winter. These conditions are critical for the state's farmers, as they prepare for the upcoming Rabi season. Meteorological updates remain vital for planning agriculture and daily activities.

Cultural activities thrive across the state, with grand celebrations held at Mahakaleshwar Temple in Ujjain during festivals such as Shivratri and Dhanteras. These events bring together thousands of devotees, showcasing Madhya Pradesh’s rich traditions and religious fervor.

Law enforcement agencies have marked significant achievements, including Ashoknagar Cyber Cell recovering over 70 stolen mobile phones and successful operations in Naxalite-affected regions like Kondagaon. These actions assure public safety and reinstill faith in the police.

Economically, initiatives promoting sustainable industries and entrepreneurship are steadily transforming Madhya Pradesh’s development landscape. Government support to local businesses and rural economies fosters growth and prosperity.

By balancing 7% active voice and 7% passive voice with 30% transition words, MP Breaking News delivers clear, engaging, and comprehensive Hindi news. It provides content tailored to urban and rural readers alike, making it a go-to platform for trustworthy and real-time state information.

For credible and in-depth news on Madhya Pradesh, trust MP Breaking News — your gateway to the latest stories shaping the state’s future.

Discussão (0)1
Entre ou crie uma conta para continuar
Pergunta
· Out. 18

Best Supplements for Heavy Metal Detox

In our modern world, exposure to toxic heavy metals such as lead, mercury, cadmium and arsenic is both common and cumulative—through food, air, water, and household products. According to some research, eliminating or reducing this metal burden may help support kidney, cardiovascular and neurological health. 

While true medical chelation is reserved for the most serious metal poisonings, there is emerging evidence that supportive nutrient strategies may assist the body’s natural detoxification pathways.https://detoxmetals.com/product/hmd-heavy-metal-detox/

Discussão (0)1
Entre ou crie uma conta para continuar
Anúncio
· Out. 18

InterSystems Developer Ecosystem News, Q3 2025

Hello and welcome to the Developer Ecosystem News!

The third quarter of the year was full of exciting activities in the InterSystems Developer Ecosystem. In case you missed something, we've prepared a selection of the hottest news and topics for you to catch up on!

News

🎇 New Hands-On Tutorial: RAG using InterSystems IRIS Vector Search

🎆 Be Part of Our 10-Year Anniversary Video!

💡 InterSystems Ideas News #23#24, and #25

📝 InterSystems Platforms Update Q3-2025

📝 Advisory for IRISSECURITY in InterSystems IRIS 2025.2

👨‍💻 InterSystems Early Access Programs (EAPs)

📝 [New DC Feature] Add Documentation Links to Your Articles

⌨ The August and September Article Bounty on Global Masters

🎁 Unlock Exciting New Rewards on Global Masters

Contests & Events

 
InterSystems Ideas Contest
 
Demo Games

🤝 Cambridge Developer Meetup - Building and Evaluating Agentic Generative Retrieval Systems

🤝  Boston Developer Meetup - AI / Agentic AI

🤝 Cambridge Dev Meetup - Health Tech Builders and Startups Meetup: FHIR, AI and Interoperability

🤝  Dev Meetup in São Paulo, Brazil: Gen AI & Agentic AI

📺 [Webinar] The Future of Healthcare Integration with Health Connect & InterSystems

📺 [Webinar] AI Vector Search Technology in InterSystems IRIS

👩‍💻 InterSystems at MIT Hacking Medicine 2025, Brazil

Latest Releases

⬇️ InterSystems Announces General Availability of InterSystems IRIS 2025.2

⬇️ Maintenance Release 2025.1.1 of InterSystems IRIS, IRIS for Health, & HealthShare Health Connect is now available

⬇️ InterSystems Reports Version 25.1 Release Announcement

⬇️ VS Code - ObjectScript extension now with improved telemetry

⬇️ InterSystems Cloud Services - Release Notes - 18 August 2025

Best Practices & Key Questions

❓ Key Questions: July, AugustSeptember

People and Companies to Know About 

👩‍🏫 Celebrating a Pioneer Voice in the Developer Community

👩‍🏫 Celebrating a Creative Force in the Developer Community

💼 MUMPS DTM to InterSystems IRIS Database Conversion Expert

💼 Opportunity for Cache Object Script Developers

💼 Hiring InterSystems IRIS for Health Developer – Remote (USA Only)

👨‍💻 In job search

👨‍💻 Seeking work HealthConnect experience

👨‍💻 IRIS Data Platform Specialist | 10+ years exp | Looking for the next job

So...

Here is our take on the most interesting and important things! 

What were your highlights from this past quarter? Share them in the comments section, and let's remember the fun we've had!

Discussão (0)1
Entre ou crie uma conta para continuar