Find

Article
· Feb 12 2m read

第二十二章 P - R 开头的术语

第二十二章 P - R 开头的术语

程序员模式 (programmer mode)

系统

所有程序开发活动进行的模式。在程序员模式下,你从 IRIS 提示符启动程序,并且每个运行的程序结束后提示符会重新出现。程序员模式涵盖了 IRIS 环境及其所有可调用的程序,包括 SQL 开发环境。在程序员模式下,你可以创建用户随后在应用程序模式下运行的应用程序。

项目 (project)

系统

用户定义的相关源文档(如例程或类定义)列表。Visual Studio Code 使用项目来帮助组织应用程序开发。

属性 (property)

对象(Objects)

表示与类相关联的特定特性的一个数据元素。该类的每个对象包含属性的字面值或指向表示数据的另一个对象的引用。一个类的所有属性共同表示其状态。

属性排序 (property collation)

对象(Objects)

Discussion (0)1
Log in or sign up to continue
Question
· Feb 12

SQL SYS.Database table not found

Hi,

I running an SQL so I can find the databases with the largest amount of free space. This is in case I can compact the databases.

However SQL cannot find the SYS.Database table.

Can someone please explain how to fix?

[SQL]TEST:%SYS>>select * from SYS.Database
ERROR #5540: SQLCODE: -30 Message:  Table 'SYS.DATABASE' not found

[SQL]TEST:%SYS>>  << entering multiline statement mode, 'GO' to execute >>
   1>>select DatabaseName, Directory, Size, Free, DiskFreeSpace
   2>>from SYS.Database
   3>>order by DiskFreeSpace DESC
   4>>go
ERROR #5540: SQLCODE: -30 Message:  Table 'SYS.DATABASE' not found

The documentation I'm using is:

https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic....

This states:

SQL Table Name: SYS.Database

Thanks

3 Comments
Discussion (3)1
Log in or sign up to continue
Article
· Feb 12 5m read

IRIS %Status y Excepciones

Podéis encontrar errores en cualquier punto de la ejecución del programa, y hay varias formas de generarlos y manejarlos en IRIS. En este artículo, exploraremos cómo gestionar excepciones de manera eficiente.

Uno de los tipos de retorno más utilizados es %Status, que los métodos emplean para indicar éxito o fallo. Vamos a empezar hablando de los valores de %Status.

Trabajando con %Status

El tipo %Status representa errores o éxito. Muchos métodos del sistema devuelven %Status cuando ocurre un error. Podéis crear una estructura similar para errores en vuestra aplicación o convertir excepciones en %Status dentro del código. Incluso cuando habéis planteado excepciones en el código.

Vamos a empezar creando errores.

Macros

Cuando hablamos de errores, las macros son esenciales y facilitan la creación de valores %Status en el código. IRIS proporciona varias macros para generar y manejar errores dentro de vuestra aplicación.

La macro más utilizada es $$$ERROR.

$$$ERROR

La macro $$$ERROR está diseñada específicamente para generar y devolver un valor %Library.%Status. Es vuestra responsabilidad verificar el estado antes de continuar con la ejecución del programa. Esta macro está estrechamente relacionada con los errores generales del sistema. Tened en cuenta los siguientes puntos al utilizarla:

  • El primer argumento (códigos de error) hace referencia a códigos de error generales en el archivo %occErrors.
  • Si usáis errores predefinidos de ese archivo, podéis utilizar la macro directamente, con o sin argumentos adicionales.

Nota: Antes de continuar, podéis usar $SYSTEM.OBJ.DisplayError(status) o $SYSTEM.Status.DisplayError(status) para mostrar los errores y admitir la traducción de cadenas de texto para los errores.

Set sc = $$$ERROR($$$NamespaceDoesNotExist,"TEST")
Do $SYSTEM.OBJ.DisplayError(sc)

output: ERROR #5015: Namespace 'TEST' does not exist1
Set sc = $$$ERROR($$$UserCTRLC)
Do $SYSTEM.OBJ.DisplayError(sc)

ouput: ERROR #834: Login aborted1

Si utilizáis un código de error que no esté listado en %occErrors, se devolverá un error de "Código de estado desconocido" o "Unknown status code". Para mensajes de error generales, usad siempre el código de error predefinido $$$GeneralError == 5001.

Ejemplo de código de estado desconocido

Set sc = $$$ERROR(95875,"TEST Error")
Do $SYSTEM.Status.DisplayError(sc)

output: ERROR #95875: Unknown status code: 95875 (TEST Error)
Set sc = $$$ERROR($$$GeneralError,"TEST Error")
Do $SYSTEM.OBJ.DisplayError(sc)

output: ERROR #5001: TEST Error

$$$ADDSC

El %Status no almacena solo un error, sino que puede contener varios. Vuestro programa puede validar múltiples condiciones y registrar todos los errores en un único estado usando la macro $$$ADDSC.Por ejemplo, el método %ValidateObject() puede devolver varios errores en una sola respuesta utilizando esta funcionalidad.

La macro $$$ADDSC agrega un estado a otro, permitiendo combinar múltiples errores en un solo código de estado. El método $SYSTEM.Status.AppendStatus realiza la misma función, facilitando el manejo de múltiples errores en una respuesta unificada.

$$$ADDSC(sc1, sc2) o $SYSTEM.Status.AppendStatus(s1, s2) añaden sc2 a sc1, devolviendo un nuevo código de estado con ambos errores combinados.

ClassMethod AppendErrors()
{
    Set sc1 = $$$ERROR($$$UserCTRLC) 
    Set sc2 = $$$ERROR($$$NamespaceDoesNotExist,"TEST")
    Set sc = $$$ADDSC(sc1,sc2)
    Do $SYSTEM.Status.DisplayError(sc)
    Write !
    Set sc = $$$ADDSC(sc1,sc2)
    Do $SYSTEM.Status.DisplayError(sc)
}
output
LEARNING>do ##class(Learning.ErrorHandling).AppendErrors()
 
ERROR #834: Login aborted
ERROR #5015: Namespace 'TEST' does not exist
 
ERROR #834: Login aborted
ERROR #5015: Namespace 'TEST' does not exist

¡Ambos resultados son lo mismo!

$$$GETERRORCODE

La macro $$$GETERRORCODE(status) devuelve el valor del código de error del %Status. Esta macro pertenece al archivo %occStatus.inc

    Set status = $$$ERROR($$$UserCTRLC) 
    Write $$$GETERRORCODE(status),!
    #;output: 834
    Set status = $$$ERROR($$$GeneralError,"TEST Error")
    Write $$$GETERRORCODE(status)
    #;output: 5001

$$$GETERRORMESSAGE
La macro $$$GETERRORMESSAGE(sc, num) devuelve la parte del mensaje de error basado en el número num del %Status. Aquí va un ejemplo.

ClassMethod GetErrorMsgMacro()
{
	Set status = $$$ERROR($$$GeneralError,"TEST Error",1,$$$ERROR($$$GeneralError,"TEST Error2"))
	write $$$GETERRORMESSAGE(status),! ; It prints "TEST Error"
	#;
	Set st = $$$GETERRORMESSAGE(status,3) ; it get the "$$$ERROR($$$GeneralError,"TEST Error2")" in 3rd position based on the 2nd argument 
	write $$$GETERRORMESSAGE(st),! ; it prints TEST Error2
}

LEARNING>Do ##class(Learning.myexcept).GetErrorMsgMacro()
TEST Error
TEST Error2

 

Validar un %Status que se ha devuelto como resultado

Ahora que habéis creado el error y lo habéis devuelto a vuestro programa, el siguiente paso es validar si la respuesta devuelta es correcta o errónea.

La macro $$$ISERR comprueba si el estado representa un error. Devuelve 1 si el estado indica un error, en caso contrario devuelve 0. Hay otra macro, $$$ISOK, que devuelve 1 cuando el estado es correcto.

Visualización de errores

Si vuestro programa falla inesperadamente (siempre esperad lo inesperado), necesitáis mostrar el mensaje de error. La clase %SYSTEM.Status está específicamente diseñada para ver o crear valores %Status (si preferís no utilizar macros) y ya hemos visto los ejemplos anteriores.

Aquí hay métodos equivalentes en %SYSTEM.Status que sustituyen a las macros:

Macro Methods
$$$ISERR $SYSTEM.Status.IsError()
$$$ISOK $SYSTEM.Status.IsOK()
$$$ADDSC $SYSTEM.Status.AppendStatus()
$$$ERROR $SYSTEM.Status.Error()
$$$OK $SYSTEM.Status.OK()
$$$GETERRORCODE $SYSTEM.Status.GetErrorCodes()

Las Excepciones continuarán en el próximo artículo.

Discussion (0)0
Log in or sign up to continue
Article
· Feb 12 5m read

Utilizando API REST, Flask e IAM com o InterSystems IRIS - Parte 3 – IAM

Utilizando Flask, API REST e IAM com o InterSystems IRIS

Parte 3 – IAM

 

O InterSystems API Manager (IAM) é um componente que permite monitorar, controlar e gerir o tráfego de APIs baseadas em HTTP. Ele também atua como uma API gateway entre aplicações e servidores InterSystems IRIS. 

 

O documento publicado em https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_apimgr traz as informações sobre o produto.

 

Já o documento https://docs.intersystems.com/components/csp/docbook/DocBook.UI.Page.cls?KEY=CIAM3.0_install traz todas as informações para a instalação e configuração do IAM.

 

Após instalar o IAM vamos ativar o mesmo e configurar um serviço, rota e plugin para criar um Rate Limiting para a nossa API REST.

 

Primeiro, após instalar o IAM vamos ativa-lo conforme definido na documentação:

 

 

Uma vez ativado o IAM vamos abrir a interface de administração para criar o serviço, rota e plugin necessários. Para isso no navegador acessamos o servidor na porta 8002:

 

 

Nesta tela vemos as opções de manutenção de serviço, rota e plugins, que são as tarefas que vamos realizar. Primeiro vamos criar o serviço para atender a nossa API REST. Clique no menu lateral em Services e na sequencia em New Service:

 

 

Informe o nome (cliente-service) e na opção Add using URL informe em URL o caminho da API (http://192.168.0.13/iris/rest/servico/cliente nonosso exemplo). Clique em Create e o serviço estará criado:

 

 

Agora vamos criar a rota. No menu lateral clique em Routes e a seguir em New Route.

 

 

 

Selecione o serviço que criamos, informe um nome para a rota (cliente-route por exemplo), informe os protocolos que poderão ser usados (http e https), informe o host (192.168.0.13) e os métodos (GET,PUT,POST,DELETE). Clique no link Add Path e informe o path para esta rota (/api/cliente). Clique em Create e a rota estará criada:

 

 

 

 

 

 

 

Agora vamos criar o plugin de rate Limiting. Este plugin limita o número de solicitações que um usuário pode fazer em um determinado período de tempo. Para isso volte ao menu lateral e clique em Plugins e na sequencia em New Plugin. Na caixa de pesquisa digite Rate e veja os plugins listados:

 

 

 

Selecione o plugin Rate Limiting Advanced. Será a presentada a tela de configuração do plugin:

 

 

 

 

Na tela de configuração mude a opção para Scoped. Selecione o serviço que criamos. Informe a quantidade de acessos em Config.Limit (5 por exemplo) e o tempo de intervalo em Config.Window.Size (60 por exemplo). Mude Config.Strategy para local e clique em Create. Pronto. Nosso plugin está criado e já está trabalhando:

 

 

 

Agora vamos precisar fazer uma alteração no nosso código python para consumir a nossa API através do IAM. Para isso vamos mudar o endereço da URL da API para o endereço que criamos na Rota do IAM:

 

API_URL = “http://192.168.0.13/iris/rest/servico/cliente” - Código Original

 

API_URL = “http://192.168.0.13:8000/api/cliente“ - Nova URL passando pelo IAM

Reative o servidor do Flask e volte a página da aplicação. Desta vez dê uma sequencia de refresh (F5) de forma a chamar a  API diversas vezes. Veja que na 6ª  chamada da API temos uma falha:

 

 

A nossa aplicação não está preparada para tratar a falha no HTTP status. Vamos fazer alguns ajustes. Primeiro vamos criar na pasta templates uma página de erro chamada erro.html:

 

<!DOCTYPE html>

<html lang="pt-br">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Erro</title>

</head>

<body>

    <h1>Ocorreu um erro!</h1>

    <p>Código de erro: {{ status_code }}</p>

    <p>Mensagem de erro: {{ error_message }}</p>

</body>

</html>

 

Vamos voltar ao código em python e fazer um ajuste para capturar o erro. No trecho que chamaos a montagem da página de index vamos tratar um HTTP code diferente de 200:

 

Onde temos o seguinte código no rota “/”:

 

    data = response.json()

    lista = data["clientes"]

    return render_template("index.html", registros=lista)

 

Mudamos para:

 

  if response.status_code == 200:

        data = response.json()

        lista = data["clientes"]

        return render_template("index.html", registros=lista)

  else:

        return render_template('erro.html', status_code=response.status_code, error_message=response.json().get('message', 'Erro desconhecido'))

 

Vamos reiniciar a aplicação Flask e mais uma vez vamos chamar a API diversas vezes. Desta vez vamos receber uma tela de erro tratado:

 

 

 

Podemos então ver que o IAM já está trabalhando, recebendo as requisições e aplicando os plugins configurados. De acordo com nossa configuração o IAM restringiu o acesso a API devolvendo um HTTP status 429 conforme configurado no plugin.

 

Voltando a tela de administração no IAM podemos ver já algumas informações sobre o consumo do serviço:

 

 

Podemos ver a quantidade de requisições que foram feitas ao serviço por HTTP Status por exemplo. Podemos também mudar a forma de visualização do gráfico:

 

 

O IAM é uma ferramenta poderosa que agrega diversas vantagens ao Iris e permite uma série de ações com seus plugins. O IAM pode ser um aliado poderoso para a publicação de serviços.

 

Até a próxima!

Discussion (0)1
Log in or sign up to continue
Article
· Feb 12 6m read

Utilizando API REST, Flask e IAM com o InterSystems IRIS - Parte 2 – Aplicativo Flask

Utilizando Flask, API REST e IAM com o InterSystems IRIS

Parte 2 – Aplicativo Flask

 

Flask é um microframework de desenvolvimento web escrito em Python. Ele é conhecido por ser simples, flexível e permitir o desenvolvimento rápido de aplicações. 

A instalação do Flask é muito simples. Depois de ter o python instalado corretamente no seu sistema operacional precisamos instalar a biblioteca flask com o comando pip. Para o consumo de API REST é aconselhado o uso da biblioteca requests. O link a seguir traz um guia para a instalação do flask: https://flask.palletsprojects.com/en/stable/installation/

 Instalado o flask, vamos então começar com a estrutura do nosso aplicativo. Vamos criar os diretórios e sub-diretórios para acomodar nossos arquivos:

 

/--+

   |

   +-- static

   |

   +-- templates

 

Vamos então seguir essa definição. Por exemplo, em c:\temp vamos criar o diretório flask e abaixo vamos criar os sub-diretórios static e template.

Siga a documentação de instalação e instale e configute o venv. Depois instale a biblioteca flask como o comando pip. A documentação do flask mostra o comando. Lembre-se que você precisa já ter o python instalado.

Depois de instalar a biblioteca flask, instale a biblioteca requests com o pip, da mesma forma que instalou o flask.

No diretório flask vamos colocar nossa aplicação python. A seguir o código da aplicação:

from flask import Flask, render_template, request, redirect, url_for

import requests

from requests.auth import HTTPBasicAuth

 

app = Flask(__name__)

 

API_URL = "http://192.168.0.13/iris/rest/servico/cliente"

USERNAME = "_SYSTEM"

PASSWD = "SYS"

 

# Rota para Listar Registros

@app.route('/')

def index():

 

    response = requests.get(API_URL, auth=HTTPBasicAuth(USERNAME, PASSWD))

    data = response.json()

    lista = data["clientes"]

    return render_template("index.html", registros=lista)

 

# Rota para Exibir o Formulário de Inclusão

@app.route('/incluir', methods=['GET'])

def incluir():

    return render_template("form.html", registro={"id": "", "nome": "", "idade": ""}, acao="Incluir")

 

# Rota para Criar um Novo Registro

@app.route('/criar', methods=['POST'])

def criar():

    dados = {

        "nome": request.form["nome"],

        "idade": request.form["idade"]

    }

    requests.post(API_URL, json=dados, auth=HTTPBasicAuth(USERNAME, PASSWD))

    return redirect(url_for("index"))

 

# Rota para Exibir o Formulário de Edição

@app.route('/editar/<int:id>', methods=['GET'])

def editar(id):

    response = requests.get(f"{API_URL}/{id}", auth=HTTPBasicAuth(USERNAME, PASSWD))

    registro = response.json() if response.status_code == 200 else {"id": "", "nome": "", "idade": ""}

    return render_template("form.html", registro=registro, acao="Editar")

 

# Rota para Atualizar um Registro Existente

@app.route('/atualizar/<int:id>', methods=['POST'])

def atualizar(id):

    dados = {

        "nome": request.form["nome"],

        "idade": request.form["idade"]

    }

    requests.put(f"{API_URL}/{id}", json=dados, auth=HTTPBasicAuth(USERNAME, PASSWD))

    return redirect(url_for("index"))

 

# Rota para Deletar um Registro

@app.route('/deletar/<int:id>')

def deletar(id):

    requests.delete(f"{API_URL}/{id}", auth=HTTPBasicAuth(USERNAME, PASSWD))

    return redirect(url_for("index"))

 

if __name__ == "__main__":

    app.run(debug=True)

 

O código é bem simples, temos as rotas de inclusão, alteração, deleção, uma rota para listar os registros existentes e dar acesso as opções de manutenção, e os formulários de inclusão e alteração.

Agora vamos para o sub-diretório static. Nele vamos colocar nosso arquivo de CSS style.css:

 

body {

    ;

    text-align: center;

    margin: 20px;

}

 

table {

    width: 60%;

    margin: auto;

    border-collapse: collapse;

}

 

th, td {

    border: 1px solid black;

    padding: 8px;

}

 

a {

    text-decoration: none;

    color: blue;

}

 

E no sub-diretório templates vamos colocar nossos arquivos HTML index.html e form.html:

index.html

<!DOCTYPE html>

<html lang="pt">

<head>

    <meta charset="UTF-8">

    <title>CRUD Flask</title>

    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

</head>

<body>

    <h2>Lista de Registros</h2>

    <a href="{{ url_for('incluir') }}">Adicionar Novo</a>

    <table border="1">

        <tr>

            <th>ID</th>

            <th>Nome</th>

            <th>Idade</th>

            <th>Ações</th>

        </tr>

        {% for reg in registros %}

        <tr>

            <td>{{ reg.id }}</td>

            <td>{{ reg.nome }}</td>

            <td>{{ reg.idade }}</td>

            <td>

                <a href="{{ url_for('editar', id=reg.id) }}">Editar</a> |

                <a href="{{ url_for('deletar', id=reg.id) }}" onclick="return confirm('Tem certeza?')">Excluir</a>

            </td>

        </tr>

        {% endfor %}

    </table>

</body>

</html>

 

form.html

 

<!DOCTYPE html>

<html lang="pt">

<head>

    <meta charset="UTF-8">

    <title>{{ acao }} Registro</title>

</head>

<body>

    <h2>{{ acao }} Registro</h2>

    <form method="POST" action="{{ url_for('criar' if acao == 'Incluir' else 'atualizar', id=registro.id) }}">

        <label>Nome:</label>

        <input type="text" name="nome" value="{{ registro.nome }}" required><br>

        <label>idade:</label>

        <input type="text" name="idade" value="{{ registro.idade }}" required><br>

        <button type="submit">{{ acao }}</button>

    </form>

    <a href="{{ url_for('index') }}">Voltar</a>

</body>

</html>

 

Para executar a aplicação basta ir para o diretório onde estamos com nossa aplicação python (no nosso caso, c:\temp\flask), ativar o venv (ambiente virtual) e executar a aplicação:

 

 

Agora podemos acessar nossa aplicação acessando a porta 5000 com um navegador:

 

Clicando no link Adicionar Novo temos a tela de inclusão de registros na nossa classe:

 

Voltando a tela de index, selecionado Alterar em algum registro, temos a tela de alteração:

 

E, novamente voltando a tela de index, clicando em Excluir vamos para a confirmação da deleção:

 

 

Com isso terminamos esta parte do artigo. Já temos a nossa classe persistente criada, a API REST publicada e uma aplicação em flask consumindo esta API com a biblioteca requests para realizar a manutenção básica (CRUD) nos nossos registros.

 

Até a próxima!

Discussion (0)1
Log in or sign up to continue