Antes de utilizar este documento, leia as informações gerais em Notas de Documentação para IBM Rational Developer para System z.
Esta edição se aplica ao Common Access Repository Manager para versão 8.0.3 do IBM Rational Developer for System z (número do produto 5724-T07) e a todas as liberações e modificações subsequentes até que seja indicado de outra forma em novas edições.
Solicite as publicações pelo telefone ou fax. O IBM Software Manufacturing Solutions recebe os pedidos de publicações entre 8h30 e 19h, horário padrão na costa leste dos Estados Unidos. O número de telefone é (800) 879-2755. O número de fax é (800) 445-9269. O fax deve ser enviado para: Publications, 3rd floor.
Você também pode solicitar as publicações através de um representante IBM ou da filial da IBM que atende em sua região. As publicações não são guardadas no endereço abaixo.
A IBM agradece pelo seu comentário. Você pode enviar os comentários por correio ao seguinte endereço:
Ao enviar informações à IBM, você concede à IBM o direito não-exclusivo de utilizar ou distribuir as informações da forma que julgar apropriada, sem incorrer em qualquer obrigação para com o Cliente.
Nota sobre Direitos Restritos para Usuários do Governo dos Estados Unidos - Uso, duplicação e divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corp.
Este manual explica como desenvolver gerenciadores de acesso a repositório (RAMs) e clientes Common Access Repository Manager (CARMA). Ele inclui os seguintes tópicos:
É possível usar este documento como um guia para essas tarefas ou como uma referência de programação.
Este manual destina-se a programadores de aplicativo ou a qualquer pessoa que deseja saber como RAMs e clientes são desenvolvidos.
Para usar este manual como guia para desenvolvimento de RAM, é preciso estar familiarizado com o SCM para o qual você está desenvolvendo um RAM. Para usar este manual para desenvolvimento de cliente CARMA, você deve entender os conceitos genéricos do SCM.
Em todo este manual, há diversas referências a conjuntos de dados e membros com o qualificador de alto nível FEK. Dependendo de como o host do CARMA foi configurado, esses conjuntos de dados podem realmente ter nomes de arquivo diferentes. Por exemplo, a biblioteca de amostra referida como FEK.SFEKSAMP neste manual pode na verdade ser chamada de MYCORP.TEST.SFEKSAMP no sistema host. Assim, dependendo da configuração do sistema host, o FEK nos nomes de conjuntos de dados referenciados neste manual podem ser substituídos por alguma outra sequência. Entre em contato com o programador de sistema para determinar se esses conjuntos de dados estão de fato localizados no sistema host.
CARMA é uma biblioteca que fornece uma interface genérica aos gerenciadores de configuração de software (SCMs) do z/OS. Os desenvolvedores podem construir sobre o CARMA desenvolvendo gerenciadores de acesso a repositório (RAMs) que se conectam ao ambiente do CARMA. Os RAMs definem como o CARMA deve se comunicar com vários SCMs. Por exemplo, um host do CARMA (uma máquina host do z/OS com o CARMA nela) pode ser configurado para usar um RAM para se comunicar com repositórios IBM® Source Code Library Manager (SCLM) e outro RAM para se comunicar com seu próprio SCM customizado.
Usando o CARMA, os desenvolvedores de software cliente podem evitar escrever código especializado para acessar SCMs e permitir facilmente o suporte para qualquer SCM ao qual um RAM está disponível. O CARMA é uma DLL armazenada em um MVS PDS. Somente clientes z/OS podem acessar o CARMA diretamente. Para acessar o CARMA a partir de uma estação de trabalho, uma ponte de software entre a estação de trabalho e o host deve ser desenvolvida. Esse software ponte deve agir como um cliente para o host do CARMA e como um servidor para as estações de trabalho. Essa ponte de software acompanha o IBM Rational Developer for System z para permitir que o plug-in do CARMA acesse os hosts do CARMA.
A Figura 1 ilustra um exemplo de ambiente do CARMA.
Quatro RAMs de amostra acompanham o CARMA atualmente:
Para acessar seus próprios SCMs usando o CARMA, você precisará obter ou desenvolver RAMs adicionais. Consulte o Conceitos Gerais e o Desenvolvendo um RAM para obter mais informações sobre como desenvolver um RAM para acessar seu próprio SCM.
O CARMA suporta atualmente os seguintes conjuntos de ações genéricas:
Embora o CARMA suporte todas essas ações, é bem possível que um determinado SCM não possa suportar uma ou mais dessas ações devido ao seu design. Os desenvolvedores de RAMs que acessam tais SCMs devem seguir as diretrizes de manipulação de operações não suportadas em Lidando com Operações Não Suportadas.
O CARMA fornece também uma estrutura chamada Custom Action Framework (CAF) para a customização das ações que um RAM pode executar (consulte o Customizando uma API do RAM Usando o CAF para obter mais informações).
Arquivos de amostra foram incluídos nos pacotes de instalação do host do CARMA. Depois que o host do CARMA tiver sido configurado com êxito, você conseguirá localizar esses arquivos de amostra como membros dentro da biblioteca de amostra (FEK.SFEKSAMP). A tabela a seguir resume esses membros:
Membro em FEK.SFEKSAMP | Descrição |
---|---|
CRA390H | Cabeçalho necessário para clientes |
CRA390SD | Deck paralelo de DLL CARMA/390 |
CRA#CCLT | JCL para compilar um cliente CARMA para um PDS/E |
CRA#PCLT | JCL para compilar um cliente CARMA para um PDS |
CRA#XCLT | JCL para executar um cliente baseado em host |
CRACLISA | Código de origem do cliente de amostra |
CRADSDEF | Cabeçalho C necessário para clientes e RAMs |
CRAFCDEF | Cabeçalho C necessário para RAMs |
CRASUTIL | Código de origem para as funções de utilitário de RAM |
CRAHUTIL | Cabeçalho necessário para funções de utilitário de RAM |
CRA$VMSG | IDCAMS JCL para REPRO CRAMSG |
CRAMSGH | Arquivo de cabeçalho comum aos RAMs de PDS e SCLM de amostra |
CRAMSGO | Módulo de objeto comum aos RAMs de PDS e SCLM de amostra |
CRA#CCOB | JCL para compilar o RAM COBOL de Amostra para um PDS/E |
CRA#PCOB | JCL para compilar o RAM COBOL de Amostra para um PDS |
CRA#CRAM | JCL para compilar o RAM Esqueleto para um PDS/E |
CRA#PRAM | JCL para compilar o RAM Esqueleto para um PDS |
CRA#CSLM | JCL para compilar o RAM SCLM de mostra para um PDS/E |
CRA#PSLM | JCL para compilar o RAM SCLM de amostra para um PDS |
CRA#CPDS | RAM PDS para um PDS/E |
CRA#PPDS | RAM PDS para um PDS |
CRARAMSA | Código de origem do RAM Esqueleto |
CRA$VDEF | JCL para REPRO CRADEF |
CRA#VPDS | JCL para REPRO das mensagens do RAM PDS de amostra |
CRA#VSLM | JCL para REPRO das mensagens do RAM SCLM de amostra |
CRASPDS | Código de amostra para o RAM PDS de amostra |
CRA$VSTR | JCL para REPRO CRASTRS |
CRASSCLM | Código de amostra para o RAM SCLM de amostra |
Esta seção descreve os conceitos gerais que são essenciais para entender como o CARMA funciona. Para obter uma visão geral mais profunda desses conceitos, leia Integrating Source Code Management Systems into WebSphere Developer for zSeries CARMA (SC23-5817-00) localizado na biblioteca do IBM Rational Developer for System z (http://www.ibm.com/software/awdtools/devzseries/library/)
O CARMA visualiza todas as entidades dentro de um SCM como Instâncias de Repositório (ou RIs), membros e metadados. Instâncias de Repositório são as entidades no nível mais alto dentro de um SCM. Por exemplo, o RAM PDS de amostra usa PDSs como RIs. Os RIs podem ser bibliotecas e níveis de código diferentes, ou o que o desenvolvedor de RAM achar que faria mais sentido para clientes CARMA. Para a maioria dos SCMs, um RI deveria representar um projeto ou componente no SCM. As Instâncias de Repositório são referidas mais comumente como instâncias durante discussão mais adiante.
Membros são entidades contidas em instâncias ou em outros membros. Os membros que contêm outros membros são conhecidos como contêineres, enquanto membros que não contêm outros membros são conhecidos como membros simples.
A Figura 2 ilustra uma hierarquia simples. "Construção" e "Desenvolvimento" são instâncias de repositório, os componentes são contêineres e os arquivos de origem são membros simples.
O CARMA fornece uma interface genérica entre diversos SCMs, cada um podendo manipular operações de formas diferentes. Como não é possível prever se a operação de registro de entrada ou saída de um determinado SCM respectivamente esperará ou retornará o conteúdo de um membro, o CARMA foi projetado de um modo que as ações de registro de entrada e saída sejam operações de configuração de sinalizador. Ou seja, nenhum conteúdo de membro é passado ao SCM ou retornado dele como parte das ações de registro de entrada e saída.
Alguns SCMs podem esperar que o conteúdo de um membro seja passado durante uma operação de registro de entrada para esse membro. Um RAM para um SCM desse tipo deve tratar esse caso armazenando o conteúdo do membro em um local temporário antes de fazer a chamada de registro de entrada para o SCM.
Da mesma forma, alguns SCMs poderão retornar o conteúdo de um membro durante uma operação de registro de saída para esse membro. Um RAM para um SCM desse tipo deve tratar esse caso armazenando o conteúdo do membro em um local temporário até que o cliente recupere o conteúdo.
Muitas das funções de API do CARMA exigem que o RAM ou o cliente CARMA aloque memória para armazenar resultados ou parâmetros de função que são passados entre o RAM e o cliente CARMA. Para todas as funções diferentes de extractMember e putMember, uma matriz unidimensional precisará ser alocada pelo RAM e liberada pelo cliente para armazenar conjuntos de informações de instância, membro e outras. O diagrama a seguir ilustra como o RAM deve alocar essa matriz:
Cada elemento na matriz representada acima é do tipo de estrutura de dados type. typePtr é um ponteiro type (do tipo type*) que atua como uma manipulação para a memória alocada recentemente. Em C, essa memória pode ser alocada com o seguinte código:
typePtr = (type*) malloc(sizeof(type) * numElements);
em que numElements é o número de índices de matriz que precisam ser criados. A memória para a qual typePtr aponta deve ser liberada pelo cliente depois que não é mais necessária.
As funções putMember e extractMember usam matrizes bidimensionais para transferir conteúdo de membro, com cada linha de matriz contendo um dos registros de membro. Para extractMember, o RAM deve alocar a matriz e o cliente CARMA deve liberar a matriz. Para putMember, o cliente CARMA deve alocar e liberar a matriz. Em ambos os casos, a matriz deve ser alocada conforme ilustrado no diagrama a seguir:
charPtrPtr é um ponteiro para um ponteiro char (é do tipo char**) que serve de manipulação para uma matriz de ponteiros char (elementos do tipo char*). Os dados da matriz de caracteres bidimensional na verdade são armazenados em uma matriz de caracteres unidimensional; a ideia de linhas e colunas é puramente conceitual. A matriz de ponteiros char é usada para fornecer manipulações ao primeiro elemento de cada linha da matriz "bidimensional". Assim, na ilustração, a primeira linha da matriz bidimensional consiste nos elementos 0a e 0b, com 0a sendo o primeiro elemento dessa linha; a segunda linha consiste nos elementos 1a e 1b, com 1a sendo o primeiro elemento dessa linha; e assim por diante.
Para alocar uma matriz bidimensional como as que são requeridas para as funções extractMember e putMember, o cliente CARMA deve primeiro criar charPtrPtr. Em C, use a seguinte declaração:
char** charPtrPtr;
Se o cliente CARMA estiver alocando a matriz de caracteres bidimensional (como é o caso da função putMember) a matriz agora poderá ser alocada. Em C, o cliente CARMA deve usar o seguinte código:
charPtrPtr = (char**) malloc(sizeof(char*) * numRows); *charPtrPtr = (char*) malloc(sizeof(char) * numColumns * numRows); for(i = 0; i < numRows; i++) (charPtrPtr)[i] = ( (*charPtrPtr) + (i * numColumns) );
em que numRows é o número de linhas e numColumns é o número de colunas na matriz bidimensional. A primeira linha aloca a matriz de ponteiros char (um ponteiro para cada linha na matriz bidimensional), a segunda linha aloca a matriz que mantém os dados da matriz bidimensional e o loop for designa cada ponteiro char na matriz de ponteiros char a uma linha na matriz bidimensional.
Se o RAM estiver alocando a matriz de caracteres bidimensional (como é o caso da função extractMember) uma etapa adicional será requerida para que a matriz possa ser alocada: charPtrPtr precisa ser passado por referência ao RAM como o parâmetro contents de extractMember, ou seja, um ponteiro para charPtrPtr precisa ser passado. Isso é necessário para que o cliente tenha uma manipulação para a matriz bidimensional depois que o RAM alocou a matriz. Suponha que o RAM receba um parâmetro denominado contents do tipo char*** na função do RAM que alocará a matriz bidimensional. O RAM deve então alocar a matriz bidimensional, usando contents como manipulação para a matriz. Em C, o RAM deve usar o seguinte código para alocar a matriz bidimensional:
*contents = (char**) malloc(sizeof(char*) * numRows); **contents = (char*) malloc(sizeof(char) * numColumns * numRows); for(i = 0; i < numRows; i++) (*contents)[i] = ( (**contents) + (i * numColumns) );
em que numRows é o número de linhas e numColumns é o número de colunas na matriz bidimensional. A primeira linha aloca a matriz de ponteiros char (um ponteiro para cada linha na matriz bidimensional), a segunda linha aloca a matriz que mantém os dados da matriz bidimensional e o loop for designa cada ponteiro char na matriz de ponteiros char a uma linha na matriz bidimensional.
Independentemente de quem alocou a matriz, o cliente CARMA deve liberar a matriz de caracteres bidimensional nas funções extractMember e putMember. Em C, o cliente CARMA deve usar código semelhante ao seguinte:
free(charPtrPtr[0]); free(charPtrPtr);
Isso libera a matriz de dados antes de liberar a matriz de ponteiros char, evitando assim uma fuga de memória.
O conteúdo de membros do SCM pode ser enviado entre o RAM, o CARMA e o cliente tudo de uma vez ou em partes. Recomenda-se que o conteúdo de membros grandes seja enviado por partes para evitar a tentativa de alocar um chunk maior de memória do que está disponível.
O conteúdo será passado de/para o RAM como matrizes de caracteres bidimensionais, cada linha da matriz correspondendo a um registro no membro. Como o RAM grava ou lê de um membro, ele deve colocar o primeiro registro do membro que ele encontra no índice 0 da matriz, para que os índices da matriz e do membro correspondam.
O CARMA suporta também transferência binária de conteúdo de membro. Quando são executadas transferências binárias, o conteúdo é passado de/para o RAM como matrizes de caracteres unidimensionais.
Para corresponder a convenção das sequências de passagem no MVS, o RAM deve esperar que todos os buffers de caracteres passados a ele sejam preenchidos com espaços em vez de terminação nula. O RAM deve também configurar os buffers que estão sendo retornados ao cliente da mesma maneira. Supondo um comprimento de buffer igual a 30, a sequência "CARMA mechanic" seria passada no formato ilustrado na Figura 5, em vez do formato ilustrado Figura 6 (em que "?" representa um caractere desconhecido). Os desenvolvedores do RAM e do cliente inicializariam os buffers que eles criaram para serem preenchidos com espaços.
C | A | R | M | A | m | e | c | h | a | n | i | c | \0 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
Uma melhoria no CARMA na versão 7.1 é a capacidade do cliente CARMA de suportar buffers de caracteres de terminação nula (conforme mostrado na figura 6). Todas as sequências passadas ao RAM ainda estarão no formato mostrado na Figura 5, mas o cliente CARMA fornecido funcionará com espaço preenchido e com buffers de caracteres de terminação nula. Antes de projetar o RAM para fornecer buffers de caracteres de terminação nula, assegure-se de que ele só será usado com a versão 7.1 ou posterior de clientes CARMA, ou outro cliente apropriado.
Todas as funções executadas com êxito devem produzir um código de retorno igual a 0. Se um erro ocorrer, os desenvolvedores do RAM poderão retornar um código com base na Tabela 2 a seguir:
Tipo de erro | Intervalo |
---|---|
Erros do CARMA | 4 - 99 |
Erros Genéricos do RAM | 100 - 200 |
Erros de Ponte de Software | 201 - 500 |
Erros Específicos do RAM | 501 - 900 |
Erros do TSO | 901 - 999 |
Se um erro ocorrer, os desenvolvedores do RAM poderão retornar um código entre 100 e 200 ou entre 201 e 900. Os códigos que variam de 100 a 200 são reservados para erros genéricos que todos os RAMs podem enfrentar. Os códigos que variam de 501 a 900 devem ser usados para qualquer erro específico de um determinado RAM. Da mesma forma, o CARMA pode retornar códigos de erro entre 4 e 99, uma ponte de software criada entre o CARMA e um cliente da estação de trabalho pode retornar códigos de erro entre 201 e 500, enquanto erros do TSO podem ser sinalizados retornando códigos de erro entre 901 e 999. Consulte o Apêndice A. Códigos de Retorno para obter uma lista dos códigos de erro predefinidos. Quando um erro resulta em um código de retorno entre 501 e 900, o RAM deve preencher o buffer de erros com os detalhes do erro. Quando um erro resultar em um código de retorno entre 100 e 200, o CARMA conseguirá reconhecer o erro e colocará a mensagem de erro apropriada no buffer de erros. Se o RAM fornecer informações adicionais de erro usando seu buffer de erros, o CARMA anexará essas informações à mensagem de erro que ele produz.
O CARMA usa seu próprio sistema de criação de log. Os níveis de rastreio podem ser usados para filtrar mensagens de log geradas pelo CARMA e pelo RAM. Os níveis de rastreio disponíveis são listados na tabela a seguir:
Enumeração | Nível de Rastreio |
---|---|
-1 | Nenhum |
0 | Erro |
1 | Aviso (Warning) |
1 | Informações |
3 | Depurar |
Todas as mensagens no nível escolhido e abaixo dele serão registradas. Por exemplo, se o nível de rastreio "Informações" for escolhido, os seguintes tipos de mensagens serão registrados: informações, aviso e erro. Informações adicionais sobre criação de log são discutidas em Log (para desenvolvimento do RAM) e em Log (para desenvolvimento do cliente CARMA).
Parâmetros e valores de retorno customizados são referenciados por elementos nas matrizes de ponteiros void. Como parâmetros e valores de retorno podem ser de vários tipos de dados, os ponteiros para eles são estereotipados como void* e, em seguida, armazenados em uma única matriz. Cada matriz assim mantém o parâmetro ou os valores de retorno customizados, mas nunca ambos. O diagrama a seguir ilustra a estrutura de uma matriz de parâmetros customizados de exemplo:
em que params é um ponteiro para uma matriz void e cada voidPtr na matriz é um ponteiro void que aponta para um parâmetro. As matrizes de valor de retorno customizado devem ser estruturadas de forma semelhante.
O número de elementos que devem estar em uma matriz de parâmetro ou valor de retorno customizado depende das informações de CAF nos clusters do VSAM do CARMA (consulte Criando Registros VSAM de um Modelo do RAM). Como é responsabilidade do desenvolvedor do RAM incluir informações sobre parâmetros e valores de retorno customizados nos clusters do VSAM, o desenvolvedor do RAM já deverá saber quantos elementos incluir nas matrizes de parâmetros e valores de retorno customizados. Os desenvolvedores do cliente CARMA podem usar a função getCAFData ou getCAFData2 do CARMA para recuperar informações sobre ações, parâmetros e valores de retorno customizados para um RAM (consulte getCAFData para obter mais informações). Usando essas informações, os desenvolvedores do cliente CARMA podem determinar quantos parâmetros e valores de retorno customizados são necessários para cada ação do RAM.
Os gerenciadores de acesso a repositório (RAMs) fornecem ao CARMA acesso a SCMs específicos. Um RAM é uma biblioteca vinculada dinamicamente (DLL) que exporta pontos de entrada para todas as funções de API que ele implementa. Uma referência de função de API foi incluída no final deste capítulo.
A maioria das funções do RAM tem o seguinte padrão:
Você pode usar o arquivo de origem do RAM esqueleto, CRARAMSA (localizado na biblioteca de amostra), como ponto de início para o RAM se estiver desenvolvendo o RAM em C. Lembre-se de que o RAM deve seguir as diretrizes de estado, alocação de memória e implementação de API fornecidas neste documento; caso contrário, problemas graves poderão se desenvolver: o CARMA pode não se comunicar apropriadamente com o RAM; fugas de memória poderão se desenvolver ou, na pior das hipóteses, o CARMA ou o RAM poderá ser encerrado de forma anormal. Especificamente, leia as seguintes seções com atenção:
A construção do RAM é um processo que difere do processo de construção de um módulo de carregamento ou objeto de programa normal. Por causa dos requisitos de suporte de DLL, o processo de criar o RAM para um PDS requer maior esforço do que para um PDS/E.
O processo de criar um RAM em um PDS requer o uso do Prelinker. As etapas descritas na criação de um RAM para um PDS são estas:
A etapa de compilação requer que sejam fornecidas a cada origem as opções de compilação adequadas para produzir o código de objeto de DLL. A etapa de pré-link envolve alimentar o código do objeto no Prelinker. A saída do Prelinker é o código do objeto que é entrada válida para o vinculador. O Prelinker criará um deck paralelo que pode ser uma entrada obrigatória para que o vinculador resolva referências externas. A etapa de link final requer que o código do objeto e os decks paralelos sejam criados pelas etapas anteriores como entrada.
Para ajudar na execução de compilações envolvendo C, o procedimento da JCL CRACPL é fornecido na bilblioteca de amostra do CARMA. A JCL de amostra para criar um RAM em um PDS também é fornecida nos membros CRA#CRAM e CRA#PRAM. CRA#CRAM é compilado para PDS/E, enquanto CRA#PRAM pode ser compilado para PDS ou PDS/E. Somente CRA#PRAM (ou outra compilação para a JCL do PDS) requer CRACPL.
O processo de criar um RAM em um PDS/E envolve duas etapas. A saída desse processo é um objeto de programa.
A primeira etapa envolve o uso do compilador para gerar o código do objeto para o RAM. Depois que o código do objeto de todas as origens foi criado, ele pode ser alimentado no componente de ligação como entrada para gerar o objeto de programa do RAM.
O processo de criar um RAM em um PDS/E é mais simples do que o de criar um PDS. A JCL de exemplo é fornecida para criar os RAMs PDS, SCLM e COBOL em um PDS/E. A JCL de amostra faz uso de procedimentos padrão para executar os processos de compilação e ligação.
As funções de utilitários do RAM são fornecidas como origem de amostra que pode ser compilada para uso de qualquer RAM designado para trabalhar com o CARMA. Ela fornece acesso a métodos que são frequentemente requeridos pelos designers de RAM e com frequência são chamados diversas vezes dentro de um único RAM. Usando o módulo de utilitários do RAM e sua biblioteca de funções, os desenvolvedores poderão economizar um tempo enorme e simplificar a execução das operações do CARMA nos membros PDS.
Os métodos a seguir estão incluídos no módulo de utilitários do RAM:
Esse método inicializa uma lista de membros do PDS especificado. Ele deve ser chamado antes de chamadas para utilGetNextMember serem feitas. Uma chamada para utilCloseMemberList também deverá ser feita antes da próxima chamada para utilInitMemberList se utilInitMemberList retornar 0 para sucesso.
int utilInitMemberList(char pds[44], int* count, void** tempDataPtr)
char pds[44] | Entrada | O PDS especificado cujos membros listar |
int* count | Saída | O número de membros no PDS |
void** tempDataPtr | Saída | Informações de estado armazenadas para uso do módulo, criadas por essa chamada |
Esse método coloca o próximo membro no PDS especificado por utilInitMemberList no membro. utilGetNextMember retorna 0 para sucesso, 1 para nenhum membro restante e qualquer outro valor no caso de erro. utilCloseMemberList deve ser chamado ao concluir a leitura da lista de membros para evitar fugas de memória. Se utilGetNextMember retornar algo diferente de 0 ou 1, você não terá de chamar utilCloseMemberList.
int utilGetNextMember(char member[8], void** tempDataPtr)
char member[8] | Saída | O próximo membro no PDS (espaço preenchido se nenhum membro existir) |
void** tempDataPtr | Saída | Informações de estado armazenadas para uso do módulo, modificadas por essa chamada |
Esse método limpa a lista de membros PDS criada por utilInitMemberList. Ele deve ser chamado antes de outro utilInitMemberList ser chamado.
void utilCloseMemberList(void** tempDataPtr)
void** tempDataPtr | Entrada | Informações de estado armazenadas para uso do módulo, limpas por essa chamada |
Esse método retorna os seguintes metadados mantidos pelo ISPF disponíveis para o determinado membro PDS. Esses metadados incluem:
int utilGetAllMemberInfo(char pds[44], char member[8], memberInfo* output)
char pds[44] | Entrada | O PDS que contém o membro |
char member[8] | Entrada | O nome do membro |
memberInfo* output | Saída | As informações do membro são colocadas nessa estrutura |
Esse método retorna parte dos metadados mantidos pelo ISPF disponíveis para o determinado membro PDS, incluindo os tipos listados no método "utilGetAllMemberInfo".
int utilGetMemberInfo(char pds[44], char member[8], char* info, int ukey)
char pds[44] | Entrada | O PDS que contém o membro |
char member[8] | Entrada | O nome do membro |
char* info | Saída | Um buffer grande o suficiente para conter as informações. U_ISPF_MI_SIZE[ukey] indicará o tamanho necessário para uma determinada chave. Não será por terminação NULA, mas o espaço deve ser preenchido com o tamanho especificado em U_ISPF_MI_SIZE. |
int ukey | Entrada | Chave para as informações desejadas. Consulte o arquivo de cabeçalho Módulo de Utilitários do RAM para obter uma lista completa de chaves. |
Esse método permite que todos os metadados mantidos pelo ISPF sejam definidos. Os metadados que podem ser configurados incluem os tipos listados no método "utilGetAllMemberInfo".
int utilSetMemberInfo(char pds[44], char member[8], char info[10], int ukey)
char pds[44] | Entrada | O PDS que contém o membro |
char member[8] | Entrada | O nome do membro |
char info[10] | Entrada | As novas informações. Ukey_ZLLIB e Ukey_ZLMSEC não são suportados |
int ukey | Entrada | Chave para as informações desejadas. Consulte o arquivo de cabeçalho Módulo de Utilitários do RAM para obter uma lista completa de chaves. |
Esse método retorna todos os metadados do ISPF disponíveis para o determinado PDS.
int utilGetAllPDSInfo(char pds[44], pdsInfo* output)
char pds[44] | Entrada | O PDS sobre o qual obter todas as informações |
pdsInfo* output | Saída | As informações do PDS serão colocadas nessa estrutura |
int utilCopyPDStoPDS(char fromInstanceID[44], char frommemberID[8], char toInstanceID[44], char tomemberID[8])
char fromInstanceID[44] | Entrada | O PDS do qual copiar |
char frommemberID[8], | Entrada | O membro PDS a ser copiado |
char toInstanceID[44] | Entrada | O PDS para o qual copiar |
char tomemberID[8] | Entrada | O membro PDS a ser substituído (ou criado se não existir) |
int utilCopyPDStoSDS(char fromInstanceID[44], char frommemberID[8], char toInstanceID[44])
char fromInstanceID[44] | Entrada | O PDS do qual copiar |
char frommemberID[8], | Entrada | O membro PDS a ser copiado |
char toInstanceID[44] | Entrada | O SDS para o qual copiar (este deve existir) |
int utilCopySDStoPDS(char fromInstanceID[44],char toInstanceID[44], char tomemberID[8])
char fromInstanceID[44] | Entrada | O SDS do qual copiar |
char toInstanceID[44] | Entrada | O PDS para o qual copiar |
char tomemberID[8] | Entrada | O membro PDS a ser substituído (ou criado se não existir) |
int utilCopySDStoSDS(char fromInstanceID[44], char toInstanceID[44])
char fromInstanceID[44] | Entrada | O SDS do qual copiar |
char toInstanceID[44] | Entrada | O SDS para o qual copiar (este deve existir) |
Iniciará uma colocação em um membro PDS. Chame utilPutMemberRecs ou utilPutMemberRec até que todos os registros requeridos sejam colocados.
int utilPutMemberInit(char pds[44], char member[8], int* lrecl)
char pds[44] | Entrada | O PDS de destino |
char member[8] | Entrada | O membro PDS de destino |
int* lrecl | Saída | O lrecl, ou o tamanho do registro para o determinado PDS. (Para VB, esse será o tamanho de registro máximo.) |
Coloque diversos registros em um comprimento fixo.
int utilPutMemberRecs(char** contents, int numRecords)
char** contents | Entrada | Matriz 2-D de registros (de tamanho lrecl) a ser colocada. |
int numRecords | Entrada | O número de registros em um conteúdo de membros |
Coloque um único registro de comprimento variável.
int utilPutMemberRec(char* contents, int length)
char* contents | Entrada | Um único registro a ser colocado |
int length | Entrada | O comprimento do registro a ser colocado. (máximo de lrecl) |
Deve ser chamado para cada utilPutMemberInit, exceto no caso de uma condição de erro em utilPutMemberInit, utilPutMemberRec ou utilPutMemberRecs.
int utilPutMemberClose()
Configure o membro PDS do qual extrair.
int utilExtractMemberInit(char pds[44], char member[8], int* lrecl int* recFM, int* numRecords)
char pds[44] | Entrada | O PDS de origem |
char member[8] | Entrada | O membro PDS de origem |
int* lrecl | Saída | O lrecl, ou o tamanho do registro para o determinado PDS. (Para VB, esse será o tamanho de registro máximo.) |
int* recFM | Saída | Um Sinalizador representando o formato de registro. As opções são U_RECFM_VB, U_RECFM_FB e U_RECFM_U. |
int* numRecords | Saída | O número de registros no membro PDS. Como isso usa estatísticas do ISPF para determinar o número de registros, o valor máximo é 65535 e só será exato se as estatísticas estiverem corretas. utilExtractMemberRec retorna 1 se fora dos registros e deve ser usado para determinar com precisão quando parar de extrair. |
Para um valor igual a 65535, o membro PDS pode ter realmente mais registros.
Extrai o próximo registro.
Retorna 0 para sucesso e 1 para sem mais registro.
int utilExtractMemberRec(char* record, int* length)
char* record | Saída | Um buffer de caracteres de tamanho lrecl, para o qual o próximo registro será extraído. |
int* length | Saída | O número de caracteres gravados no registro. |
Um valor de retorno igual a 1 indica não haver mais registros e nenhum registro foi retornado nessa chamada.
Deve ser chamado para cada utilExtractMemberInit, exceto no caso de uma condição de erro em utilExtractMemberInit ou utilExtractMemberRec
int utilExtractMemberClose()
Informações adicionais sobre os métodos listados anteriormente podem ser encontradas no arquivo de cabeçalho do módulo de utilitários do RAM.
O CARMA mantém suas informações do RAM em diversos clusters do VSAM, que devem ser preenchidos com registros para cada RAM no ambiente. Consulte Customizando uma API do RAM Usando o CAF para saber como inserir os registros apropriados ao RAM nesses clusters do VSAM. Se você não precisar customizar a API do RAM, o único registro que será necessário incluir no cluster do VSAM é o registro do RAM; você não precisará incluir registros de parâmetro, valor de retorno ou ação.
Quando o CARMA tenta carregar um RAM, ele espera poder carregar as funções da API do RAM explicitamente usando a função C dllqueryfn. Se estiver usando C, uma instrução #pragma export como aquela a seguir será usada para exportar cada função do RAM. O exemplo a seguir exporta a função initRAM:
#pragma export(initRAM)
Quando um membro, uma instância ou outro tipo de dados está sendo retornado do RAM para o CARMA, seu ID e nome de exibição normalmente são retornados. O ID deve identificar exclusivamente a entidade para o RAM. Seria sensato retornar o caminho absoluto de um membro (começando pelo contêiner de nível superior) no campo de ID para que o membro possa ser acessado facilmente pelo RAM quando futuras solicitações forem feitas. O nome de exibição é simplesmente o nome que deve ser exibido no cliente.
Em sua maioria, as funções do RAM são estruturas predefinidas para passar informações de volta ao CARMA.
A estrutura Descriptor consiste em um campo de caractere de nome de 64 bytes e um campo de caractere de ID de 256 bytes. É usado para descrever instâncias, contêineres e membros simples. A estrutura KeyValPair consiste em um campo de chave de 64 bytes e um campo de valor de 256 bytes. É usado para pares de valores de chaves de metadados. Essas estruturas são resumidas na Tabela 4 e na Tabela 5.
Campo | Descrição |
---|---|
char id[256] | ID exclusivo para descrever a entidade |
char name[64] | Nome de Exibição |
Campo | Descrição |
---|---|
char key[64] | Um índice |
char value[256] | Os dados |
CRAFCDEF, um arquivo de cabeçalho C na biblioteca de amostra, deve ser incluído no código do RAM para que você possa usar essas estruturas de dados.
O CARMA fornece aos RAMs um ponteiro para uma função de criação de log, um ponteiro para um arquivo de log e um nível de rastreio (consulte a Tabela 3) na inicialização. O nível de rastreio deve ser usado para filtrar algumas mensagens que possam não interessar aos usuários. A função de criação de log obtém um buffer de caracteres de remetente de 16 bytes, um buffer de caracteres de mensagem de 256 bytes e o ponteiro de arquivo de log que é passado na inicialização. Segue um exemplo de chamada em C:
if(traceLevel > 1) (*writeToLog)("MyRAM", "Gathering instances", logPtr);
A tarefa em spool indicará o nome do log criado.
Se você estiver desenvolvendo um RAM que se comunica com um SCM que não suporta uma operação do CARMA, informe ao cliente que ela está desativada, modificando apropriadamente as informações do CAF do RAM (consulte o Customizando uma API do RAM Usando o CAF). Você pode assumir que os clientes CARMA não chamarão ações marcadas como desativadas. Entretanto, conte ainda com a possibilidade de um cliente chamar uma ação desativada executando uma das duas seguintes ações:
Parâmetros customizados são passados ao RAM usando o parâmetro void** params. params é uma matriz de ponteiros void que apontam para variáveis de diversos tipos. Se esses parâmetros customizados tiverem de ser definidos como parâmetros obrigatórios para uma determinada função nos clusters do VSAM do CARMA (consulte Customizando uma API do RAM Usando o CAF para obter mais informações), deverá ser assumido que o cliente configurou params corretamente. Para recuperar os parâmetros, basta estereotipar as variáveis em params novamente aos seus tipos adequados. Observe como params usa um char* para sequências, em vez de um char**. Use o seguinte código C como exemplo:
int param0; char param1[30]; double param2; param0= *( (int*) params[0]); memcpy(param1, params[1], 30); param2 = *( (double*) params[2]);
Um ponteiro para uma matriz de valores de retorno customizados não alocados é passado ao RAM como void*** customReturn. Se valores de retorno customizados forem definidos nos clusters do VSAM do CARMA, o RAM deverá alocar memória para customReturn e preenchê-la apropriadamente. Como o cliente deve liberar a memória criada no RAM, é importante que os desenvolvedores do RAM aloquem memória para cada valor de retorno separadamente. O seguinte código C demonstra o retorno de int, string e double:
/* Estes são definidos no início */ int* return0; char* return1; double* return2; /* Corpo do programa */ return0 = malloc(sizeof(int)); *return0 = 5; return1 = malloc(sizeof(char) * 10); memcpy(return1, "THE STRING", 10); return2 = malloc(sizeof(double)); *return2 = 3.41; /* Alocar e preencher a estrutura de valor de retorno */ *customReturn = malloc(sizeof(void*) * 3); (*customReturn)[0] = (void*) return0; (*customReturn)[1] = (void*) return1; (*customReturn)[2] = (void*) return2;
Se nenhum valor de retorno estiver definido nos clusters do VSAM do CARMA, customReturn deverá ser configurado como NULL.
O RAM fornece a capacidade de sugerir extensões de arquivo para recursos do CARMA nos clientes CARMA que usam o RAM. As extensões de arquivo fornecem ao cliente insight sobre o editor apropriado para uso com um recurso do CARMA específico. Permitir que o RAM especifique a extensão de arquivo elimina a necessidade de o usuário especificar extensões em cada recurso.
As extensões podem ser adquiridas de três fontes diferentes:
O RAM pode ser configurado para sugerir extensões de arquivo ao cliente que possam ser usadas em conjunto com os recursos do CARMA. Por exemplo, supondo que a propriedade de metadados do RAM "carma.file-extension" esteja configurada como "foo" e o cliente esteja configurado para consultar o RAM em busca de uma extensão. O nome do arquivo para o recurso do CARMA "Name" seria exibido no cliente como "Name.foo". Isso se deve ao fato de que o CARMA consultará o RAM em busca de uma extensão de arquivo se o cliente estiver configurado para aceitar uma extensão do RAM. Por padrão, o RAM não sugere a extensão de arquivo. Entretanto, pode-se assumir que o cliente fornecerá uma extensão se uma não tiver sido fornecida ainda pelo RAM.
Nome de Exibição | Propriedade de Metadados do RAM (carma.file-extension) | Propriedade de Extensão de Cliente (configurada para aceitar a sugestão do RAM) | Nome do Arquivo no Cliente |
---|---|---|---|
Nome | .foo | <unset> | Name.foo |
Entretanto, depois que o RAM tiver especificado a extensão de arquivo, fica a critério do cliente aceitar a extensão de arquivo sugerida ou usar uma definida no cliente. No exemplo fornecido na Tabela 6, a extensão fornecida pelo RAM foi "foo", de modo que o recurso do CARMA "Name" foi exibido no cliente como "Name.foo". Supondo agora que o cliente foi configurado para não usar a extensão fornecida pelo RAM e aplicar uma sua própria. O arquivo "Name.foo" seria alterado para exibir "Name.ext", em que "ext" é a nova extensão especificada no cliente. Se o nome de exibição já tiver uma extensão de arquivo associada a ele, o cliente não poderá removê-la; ele só poderá anexar uma nova extensão ao nome de arquivo existente.
Nome de Exibição | Propriedade de Metadados do RAM (carma.file-extension) | Propriedade de Extensão de Cliente (configurada para ignorar a sugestão do RAM) | Nome do Arquivo no Cliente |
---|---|---|---|
Nome | .foo | .ext | Name.ext |
Name.foo | <unset> | .ext | Name.foo.ext |
Se uma extensão de arquivo não estiver predefinida na propriedade de metadados do RAM (carma.file-extension = <unset>), um recurso do CARMA direcionará a si mesmo para o cliente para obter uma extensão. Se o cliente não especificar uma extensão de arquivo também, o recurso do CARMA herdará a extensão padrão de seu contêiner-pai.
Nome de Exibição | Propriedade de Metadados do RAM (carma.file-extension) | Propriedade de Extensão de Cliente | Nome do Arquivo no Cliente |
---|---|---|---|
Nome | <unset> | <unset> | Name.dft |
O RAM fornece a capacidade de rastrear todas as versões disponíveis dos membros do CARMA com o uso de uma chave de metadados específica: carma.version. Ao fornecer a chave carma.version na lista de informações do membro, o CARMA possibilita oferecer funcionalidade específica para recursos com versão. Por exemplo, os membros do CARMA que suportam rastreamento de versão podem diferir dos membros que não suportam. As ações disponíveis nos membros ativados para versão dependem do SCM do qual o membro se origina, bem como do RAM usado para conectar-se ao SCM. Cabe ao desenvolvedor do RAM decidir que ações ativar, como tornar as versões editáveis, somente leitura, ou fornecer acesso a versões anteriores. Quando o CARMA executa funções nos membros que foram ativados para versão, por padrão, as funções sempre farão referência à versão mais recente de um membro, a menos que o contrário seja especificado.
O uso da chave de informações do membro não identifica exclusivamente o membro do CARMA. Cada membro do CARMA com versão deve ter um ID de membro exclusivo a fim de indicar qual versão está sendo considerada especificamente. Por exemplo, um membro do CARMA com o ID "member1" tem 2 versões - 1 e 2. As versões do membro podem ser identificadas exclusivamente, anexando um número de versão ao ID. Consulte o exemplo na Tabela 9. O RAM deve estar apto a identificar exclusivamente a versão do membro com base no ID a fim de oferecer funcionalidade para suportar membros com versão - como checkin, extractMember, performAction, etc.
Versão do Membro | Exemplo de ID do Membro |
---|---|
Versão 1 | member1_v1 |
Versão 1.1 | member1_v1.1 |
Versão 2 | member1_v2 |
Para obter informações detalhadas sobre a chamada de listas de versões para membros do CARMA, consulte a seção getVersionList.
O RAM tem três funções de estado: initRAM, terminateRAM e reset, conforme ilustrado na Figura 8. initRAM inicializa as variáveis globais do RAM e estabelece a conexão com o repositório. Não será possível chamá-la novamente em uma sessão até que o RAM tenha sido finalizado. reset restaura a conexão do repositório com seu estado inicial. É possível chamá-la a qualquer momento, exceto imediatamente após terminateRAM. terminateRAM também pode ser chamada a qualquer momento, mas a única função que pode ser chamada com êxito imediatamente após terminateRAM é initRAM.
int initRAM(Log_Func logFunc, FILE* log, int traceLev, char locale[8], char codepage[5], char error[256])
Log_Func logFunc | Entrada | Um ponteiro de função para a função de criação de log do CARMA. Isso deve ser armazenado para uso em outras funções do RAM. |
FILE* log | Entrada | Um ponteiro de arquivo para o log do CARMA. Isso deve ser armazenado para uso com a função de criação de log. |
int traceLev | Entrada | O nível de rastreio de criação de log a ser usado em toda a sessão. |
char locale[8] | Entrada | Informa ao CARMA o código de idioma das sequências que serão retornadas ao cliente |
char codepage[5] | Entrada | Informa ao CARMA a página de códigos das sequências que serão retornadas ao cliente |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
initRAM deve ser chamado antes que todas as outras operações do RAM ocorram. Deve ser usado para inicializar a conexão do SCM e configurar qualquer variável global usada no programa. Entre essas variáveis globais devem estar aquelas usadas para armazenar as três variáveis passadas nessa função.
void terminateRAM(char error[256])
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
terminateRAM deve ser usado para fechar a conexão do SCM e liberar os recursos usados pelo RAM (como memória e arquivos).
int reset(char buffer[256])
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
reset é usado para restaurar a conexão SCM com seu estado inicial.
Recupera a lista de instâncias disponíveis no SCM
int getInstances(Descriptor** records, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256])
Descriptor** records | Saída | Isso deve ser alocado e preenchido com os IDs e os nomes das instâncias disponíveis. |
int* numRecords | Saída | O número de registros que foram alocados e retornados |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de instâncias |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Operação:
*records = (Descriptor*) malloc(sizeof(Descriptor) * *numRecords);
Se não for possível consultar o SCM a respeito das instâncias, pode ser útil o cliente passar uma lista de instâncias conhecidas usando o buffer filter. O RAM deve então verificar a lista e retornar as instâncias na matriz de registros. As instâncias poderão ser codificadas permanentemente se foram constantes para o SCM.
Recupera a lista de instâncias disponíveis no SCM e os metadados associados a essas instâncias. Essa é uma função opcional. O RAM deverá implementar essa função se o SCM fornecer os metadados com a lista de instâncias. O RAM é obrigado a implementar getInstances mesmo que getInstancesWithInfo esteja implementado.
int getInstancesWithInfo(DescriptorWithInfo** records, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256])
DescriptorWithInfo** records | Saída | Isso deve ser alocado e preenchido com os IDs e os nomes das instâncias disponíveis. Para cada instância, as informações de metadados devem ser alocadas e preenchidas. |
int* numRecords | Saída | O número de registros que foram alocados e retornados |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de instâncias |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Operação:
*records = (DescriptorWithInfo*) malloc(sizeof(DescriptorWithInfo) * *numRecords);
(*records)[i].info = (KeyValPair *) malloc(sizeof(KeyValPair) * (*records)[i].infocount);
Se não for possível consultar o SCM a respeito das instâncias, pode ser útil o cliente passar uma lista de instâncias conhecidas usando o buffer filter. O RAM deve então verificar a lista e retornar as instâncias na matriz de registros. As instâncias poderão ser codificadas permanentemente se foram constantes para o SCM.
Recupera an lista de membros em uma instância
int getMembers(char instanceID[256], Descriptor** members, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256]);
char instanceID[256] | Entrada | A instância para a qual os membros devem ser retornados |
Descriptor** members | Saída | Isso deve ser alocado e preenchido com os IDs e os nomes dos membros dentro da instância. |
int* numRecords | Saída | O número de membros para os quais a matriz foi alocada |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de membros. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Operação:
*members = malloc(sizeof(Descriptor) * *numRecords);
Recupera a lista de membros disponíveis na instância especificada e os metadados associados a esses membros. Essa é uma função opcional. O cliente deverá chamar essa função se desejar recuperar uma lista de membros e os metadados associados a todos esses membros. Se o RAM não suportar essa função, o cliente deverá fazer fallback para chamar getMembers.
int getMembersWithInfo(char instanceID[256], MemberDescriptorWithInfo** members, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256]);
char instanceID[256] | Entrada | A instância para a qual os membros devem ser retornados |
MemberDescriptorWithInfo** members | Saída | Isso deve ser alocado e preenchido com os IDs e os nomes dos membros dentro da instância. Para cada membro, as informações de metadados devem ser alocadas e preenchidas. Deve ser indicado também se o membro é um contêiner. |
int* numRecords | Saída | O número de membros para os quais a matriz foi alocada |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de membros. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Operação:
*members = (MemberDescriptorWithInfo*) malloc(sizeof(MemberDescriptorWithInfo) * *numRecords);
*members)[i].info = (KeyValPair *) malloc(sizeof(KeyValPair) * (*members)[i].infocount);
Configura isContainer como true se um membro for um contêiner; caso contrário, false
int isMemberContainer(char instanceID[256], char memberID[256], int* isContainer, void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro sendo verificado |
char memberID[256] | Entrada | A instância que está sendo verificada |
int* isContainer | Saída | Deve ser configurado como 1 se o membro for um contêiner; e como 0, se não for |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Configure *isContainer como 1 se o membro for um contêiner; ou 0, se não for.
Recupera a lista de membros disponíveis em um contêiner
int getContainerContents(char instanceID[256], char memberID[256], Descriptor** contents, int* numMembers, void** params, void*** customReturn, char filter[256], char error[256])
char instanceID[256] | Entrada | A instância que mantém o contêiner |
char memberID[256] | Entrada | O ID do contêiner |
Descriptor** contents | Saída | Deverá ser alocado e preenchido com os IDs e os nomes dos membros dentro do contêiner |
int* numRecords | Saída | O número de membros para os quais a matriz foi alocada |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de membros. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Operação:
*contents = malloc(sizeof(Descriptor) * *numMembers);
Recupera a lista de membros em um contêiner e os metadados associados a esses membros. Essa é uma função opcional. O RAM deverá implementar essa função se o SCM fornecer os metadados com a lista de membros. O RAM é obrigado a implementar getContainerContents mesmo que getContainerContentsWithInfo esteja implementado.
int getContainerContentsWithInfo(char instanceID[256], char memberID[256], MemberDescriptorWithInfo** members, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256]);
char instanceID[256] | Entrada | A instância que mantém o contêiner |
char memberID[256] | Entrada | O ID do contêiner |
MemberDescriptorWithInfo** members | Saída | Isso deve ser alocado e preenchido com os IDs e os nomes dos membros dentro do contêiner. Para cada membro, as informações de metadados devem ser alocadas e preenchidas. Deve ser indicado também se o membro é um contêiner |
int* numRecords | Saída | O número de membros para os quais a matriz foi alocada |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de membros. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Operação:
*members = (MemberDescriptorWithInfo*) malloc(sizeof(MemberDescriptorWithInfo) * *numRecords);
(*members)[i].info = (KeyValPair *) malloc(sizeof(KeyValPair) * (*members)[i].infocount);
Criar e excluir fornecem a funcionalidade para criar e excluir membros e contêineres em um ambiente do CARMA.
Cria um novo membro
int createMember(char instanceID[256], char memberID[256], char name[64], char parentID[256], int* lrecl, char recFM[4], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro sendo criado |
char memberID[256] | Saída | O ID do membro que está sendo criado |
char name[64] | Entrada/Saída | O ID do membro sendo criado |
char parentID[256] | Entrada | O ID do contêiner-pai (Se nenhum pai existir, deve ser preenchido com espaço) |
int* lrecl | Saída | O número de colunas no conjunto de dados e na matriz |
char recFM[4] | Saída | Contém o formato de registro do conjunto de dados (FB, VB, ect) |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Cria um novo contêiner
int createContainer(char instanceID[256], char memberID[256], char name[64], char parentID[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o contêiner sendo criado |
char memberID[256] | Saída | O ID do contêiner que está sendo criado |
char name[64] | Entrada/Saída | O ID do contêiner sendo criado |
char parentID[256] | Entrada | O ID do contêiner-pai (Se nenhum pai existir, deve ser preenchido com espaço) |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Exclui um membro ou contêiner
int delete(char instanceID[256], char memberID[256], int force, void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro ou o contêiner sendo excluído |
char memberID[256] | Entrada | O ID do membro que está sendo excluído |
int force | Entrada | Usado para forçar uma exclusão. Um valor igual a 1 forçará uma exclusão |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
A função de exclusão pode ser usada para excluir membros e contêineres; entretanto, não deve ser usada para excluir uma Instância do RAM.
Recupera o conteúdo do membro
int extractMember(char instanceID[256], char memberID[256], char*** contents, int* lrecl, int* numRecords, char recFM[4], int* moreData, int* nextRec, void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro |
char memberID[256] | Entrada | O ID do membro que está sendo extraído |
char*** contents | Saída | Será alocado como uma matriz bidimensional para manter o conteúdo do membro |
int* lrecl | Saída | O número de colunas no conjunto de dados e na matriz |
int* numRecords | Saída | O número de registros no conjunto de dados ou o número de linhas na matriz |
char recFM[4] | Saída | Conterá o formato de registro do conjunto de dados (FB, VB, etc.) |
int* moreData | Saída | Configure como 1 o valor da variável para o qual isso aponta, se a extração tiver de ser chamada novamente (por ainda haver mais dados a serem extraídos). Caso contrário, designe como 0 o valor para o qual ela aponta. |
int* nextRec | Entrada/Saída |
Entrada: O registro do membro no qual o RAM deve iniciar a extração Saída: O primeiro registro no conjunto de dados que não foi extraído se *moreData estiver configurado como 1; caso contrário, indefinido |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
extractMember retorna o conteúdo do conjunto de dados em uma matriz bidimensional. A função foi projetada para suportar o envio dos dados em chunks, por isso a matriz não precisa ser alocada para o tamanho inteiro do arquivo. Os registros nos conjuntos de dados são considerados para serem indexados com o primeiro registro sendo 0.
Operação:
*contents = (char**) malloc(sizeof(char*) * (*numRecords)); **contents = (char*) malloc(sizeof(char) * (*lrecl) * (*numRecords)); for(i = 0; i < *numRecords; i++) (*contents)[i] = ( (**contents) + (i * (*lrecl)) );
O membro contém 26 registros, cada um contendo o próximo caractere alfabético, começando com "A" no registro 0. Seu valor *lrecl é 5, seu valor recFM é "FB" e o tamanho do chunk de dados do RAM é 10.
A Figura 9 mostra o que extractMember deve retornar para cada chamada necessária para extrair todo o conteúdo.
Primeira Chamada | Segunda Chamada | Terceira Chamada |
---|---|---|
![]() |
![]() |
![]() |
*lrecl = 5 *numRecords = 10 *moreData = 1 *nextRec = 10 |
*lrecl = 5 *numRecords = 10 *moreData = 1 *nextRec = 20 |
*lrecl = 5 *numRecords = 6 *moreData = 0 *nextRec = X |
Atualiza o conteúdo de um membro ou cria um novo membro se o memberID especificado não existir na instância
int putMember(char instanceID[256], char memberID[256], char** contents, int lrecl, int* numRecords, char recFM[4], int moreData, int nextRec, int eof, void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro |
char memberID[256] | Entrada | O ID do membro que está sendo atualizado/criado |
char** contents | Entrada | Mantém o novo conteúdo do membro |
int lrecl | Entrada | O número de colunas no conjunto de dados e na matriz |
int* numRecords | Entrada/Saída | O número de registros no conjunto de dados ou o número de linhas na matriz |
char recFM[4] | Entrada | Contém o formato de registro do conjunto de dados (FB, VB etc.) |
int moreData | Entrada | Será 1 se o cliente tiver mais chunks de dados para enviar; caso contrário, 0 |
int nextRec | Entrada | O registro no conjunto de dados para o qual o registro 0 da matriz de conteúdo é mapeado |
int eof | Entrada | Se 1, indica que a última linha da matriz deverá marcar a última linha no conjunto de dados; caso contrário, 0 |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Como extractMember, putMember suporta os dados sendo enviados em chunks. putMember também deve suportar clientes que desejam passar chunks de dados que não estão em ordem sequencial. Por exemplo, um cliente podem enviar os registros de 10 a 19, de 20 a 29 e depois de 0 a 9. O RAM deve manipular tal situação e atualizar adequadamente o membro, ou retornar um código de erro e preencher o buffer de erros com uma sequência declarando que ele não pode manipular tal situação.
numRecords descreve quantos registros o cliente gostaria de atualizar/gravar na entrada, enquanto o RAM deve configurá-lo com o número de registros que foram de fato gravados para saída. Se houver uma diferença entre os dois, o cliente tentará inserir os membros que não foram gravados. Portanto, depois de receber uma resposta do RAM, o cliente irá configurar nextRec com o novo valor numRecords mais nextRec em sua próxima chamada putMember.
Para putMember, nextRec informa ao RAM onde começar a gravar o buffer de conteúdo que foi passado. Por exemplo, se nextRec for 0, o RAM deverá começar no início do membro.
moreData significa que o cliente estará chamando putMember novamente com outro chunk. Cabe ao desenvolvedor do RAM decidir como manipular uma situação em que moreData está configurado e a próxima chamada para o RAM não é uma chamada para a função putMember que fornece o próximo chunk de dados. Nesse caso, o RAM pode simplesmente retornar um erro. Como alternativa, ele pode tratar o problema e seguir em frente.
eof significa que o buffer de conteúdo atual tem os últimos registros de um membro. Se um membro de 40 registros precisasse ser reduzido a 5 registros, eof seria configurado como 1 quando o quinto registro estivesse sendo passado. Isso nunca deve ser configurado quando moreData é igual a 1.
Consulte a origem para o RAM Esqueleto e o RAM PDS de amostra para obter mais ajuda (consulte Localizando Arquivos de Amostra para obter informações sobre como localizar esses arquivos de origem).
Operação:
O CARMA fornece aos RAMs a capacidade de extrair arquivos de um SCM em um ambiente normal do host de PDSs e arquivos sequenciais.
Copia um membro de um PDS ou um SDS.
int copyFromExternal(char instanceID[256], char memberID[256], char external[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro sendo copiado |
char memberID[256] | Entrada | O ID do membro sendo copiado |
char external[256] | Entrada | O local do qual copiar. Um membro PDS ou um membro SDS. Exemplos: FEK.#CUST.EXT.STOR FEK.#CUST.EXT.PDS(MEMBER) |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Copia um membro para um PDS ou um SDS.
int copyToExternal(char instanceID[256], char memberID[256], char target[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro sendo copiado |
char memberID[256] | Entrada | O ID do membro sendo copiado |
char target[256] | Entrada | O local para o qual copiar. Um membro PDS ou um membro SDS. Exemplos: FEK.#CUST.EXT.STOR FEK.#CUST.EXT.PDS(MEMBER) |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Para transferir com êxito arquivos que contêm dados binários sem incorrer em danos, o RAM usa um conjunto projetado de funções para extrair e colocar arquivos binários de um SCM. Depois que um membro binário foi extraído de um SCM, o RAM entrega o membro para o CARMA390, que continua a passá-lo até que o membro atinja a máquina do usuário. Em cada estágio do processo de transferência, o membro é reconhecido como contendo dados binários e nenhuma mudança é aplicada ao membro porque isso danificaria os dados.
Recupera o conteúdo de um membro binário.
int putBinMember(char instanceID [256], char memberID [256], char** contents, int* length, int* moreData, int start, void** params, void*** customReturn, char error [256])
char instanceID[256] | Entrada | A instância que contém o membro sendo extraído. |
char memberID[256] | Entrada | O ID do membro que está sendo extraído. |
char** contents | Saída | Ponteiro para o conteúdo do membro |
int* length | Saída | O comprimento do conteúdo do membro. |
int* moreData | Saída | Se a extração precisar ser chamada novamente porque há mais dados, configure como 1 o valor da variável para o qual isso aponta, ou então designe como 0 o valor para o qual ela aponta. |
int start | Entrada | O local de byte do arquivo do qual iniciar a extração. |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Atualiza o conteúdo de um membro binário ou cria um novo membro se o memberID especificado não existir na instância.
int putBinMember(char instanceID [256], char memberID [256], char* contents, int length, int moreData, int start, void** params, void*** customReturn, char error [256])
char instanceID[256] | Entrada | A instância que contém o membro sendo atualizado/criado. |
char memberID[256] | Entrada | O ID do membro que está sendo atualizado/criado. |
char* contents | Entrada | Mantém o novo conteúdo dos membros. |
int length | Entrada | Ponteiro para o comprimento dos dados a serem gravados. |
int moreData | Entrada | Será 1 se o cliente tiver mais chunks de dados para enviar; caso contrário, 0. |
int start | Entrada | O local de byte do arquivo para iniciar a colocação de dados. |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Recupera todos os metadados de um membro ou de uma instância
int getAllMemberInfo(char instanceID[256], char memberID[256], KeyValPair** metadata, int* num, void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | O ID da instância que contém o membro |
char memberID[256] | Entrada | O ID do membro para o qual metadados estão sendo retornados. O ID poderá ficar vazio (configurado como todos os espaços) se as informações do membro forem recuperadas para a instância e não para um membro específico. |
KeyValPair** metadata | Saída | Isso deve ser alocado e preenchido com todos os pares de valores de chaves de metadados para o membro especificado |
int* num | Saída | O número de pares de valores de chaves para os quais a matriz foi alocada |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Operação:
*metadata = malloc(sizeof(KeyValPair) * *num);
Recupera uma parte específica dos metadados de um membro ou de uma instância.
int getMemberInfo(char instanceID[256], char memberID[256], char key[64], char value[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | O ID da instância que contém o membro |
char memberID[256] | Entrada | O ID do membro cujos metadados estão sendo recuperados. Se configurado como todos os espaços, os metadados da instância deverão ser retornados. |
char key[64] | Entrada | A chave do valor a ser retornado |
char value[256] | Saída | O valor solicitado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
getMemberInfo retorna o valor da chave especificada para o membro determinado.
Atualiza uma parte específica dos metadados de um membro ou de uma instância.
int updateMemberInfo(char instanceID[256], char memberID[256], char key[64], char value[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | O ID da instância que contém o membro |
char memberID[256] | Entrada | O ID do membro cujos metadados estão sendo configurados. Se configurado como todos os espaços, os metadados da instância deverão ser configurados. |
char key[64] | Entrada | A chave do valor a ser configurado |
char value[256] | Entrada | O valor a ser configurado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
updateMemberInfo tenta atualizar os metadados de um membro (especificados pela chave determinada) com o valor determinado.
Bloqueia o membro
int lock(char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro |
char memberID[256] | Entrada | O ID do membro que está sendo bloqueado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Desbloqueia o membro
int unlock(char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro |
char memberID[256] | Entrada | O ID do membro que está sendo desbloqueado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Efetua o registro de entrada do membro. Isso consiste apenas em configurar um sinalizador para marcar que o registro de entrada é efetuado.
int check_in(char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro |
char memberID[256] | Entrada | O ID do membro cujo registro de entrada está sendo efetuado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Efetua o registro de saída do membro. Isso consiste apenas em configurar um sinalizador para marcar que o registro de saída é efetuado.
int check_out(char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância que contém o membro |
char memberID[256] | Entrada | O ID do membro cujo registro de saída está sendo efetuado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Executa a ação identificada no actionID usando os parâmetros fornecidos e os valores de retorno em customReturn (quando aplicável).
int performAction(int actionID, char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
int actionID | Entrada | A ação customizada que está sendo solicitada, conforme definido no CRADEF VSAM. |
char instanceID[256] | Entrada | A instância na qual a ação está sendo executada. Se este e memberID estiverem configurados como todos os espaços, isso indicará que a ação deve ser executada no RAM. |
char memberID[256] | Entrada | O membro no qual a ação está sendo executada. Se isso estiver configurado como todos os espaços, indicará que a ação deve ser executada na instância. |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Fornece uma lista de versões disponíveis para um determinado membro
int getVersionList(char instanceID[256], char memberID[256], VersionIdent** versions, int* num, void** params, void*** customReturn, char error[256])
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro para o qual obter uma lista de versões |
int* num | Saída | O número de versões |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
VersionIdent será identificado pela seguinte estrutura:
typedef struct { char memberID[256]; /*Um memberID com versão, como baseMemberID_VerNum*/ char versionKey[64]; /* Uma maneira de se referir à versão, como "1.2.3"...deve ser igual ao valor para a chave de metadados carma.version*/ char comments[256]; /* Os comentários fornecidos pelo RAM sobre a versão, podem ser registro de data/hora, mudanças, etc.. */ } VersionIdent;
A lista de versões deverá ser uma lista completa de versões ordenadas, mas o Desenvolvedor do RAM pode optar por usar um ID ‘com versão' para a versão atual ou usar o ID inalterado. Como exemplo, a versão atual de um membro pode ser acessível por meio de "location(Member)" ou "location(Member)_1.4", em que o arquivo está na versão 1.4. O desenvolvedor do RAM pode portanto optar por retornar "location(Member)_1.4" ou "location(Member)" como a versão mais recente na lista.
Ao retornar uma lista de membros por meio das funções de navegação, como getMembers, os memberIDs retornados NÃO DEVEM incluir a versão. Alterar o memberID para um membro impede que um cliente CARMA rastreie esse membro adequadamente.
Para suportar versão, os Desenvolvedores do RAM devem manipular as chamadas do CARMA quando apresentadas com um ID ‘com versão' para o memberID.
Se um desenvolvedor do RAM desejar suportar versão para alguns, mas não para todos os membros, um código de retorno 130, que significa "O membro não suporta versão" pode ser usado.
Embora a linguagem de programação C seja uma opção suficiente para o desenvolvimento da maioria dos RAMs, em determinadas ocasiões, você poderá achar benéfico desenvolver um RAM em COBOL. Saiba que existem algumas vantagens em usar COBOL para desenvolvimento do RAM, além de haver algumas desvantagens também:
O CARMA é fornecido com um RAM de amostra desenvolvido em COBOL, apropriadamente chamado de RAM COBOL de amostra. Para funcionar corretamente, esse RAM COBOL de amostra requer a origem de COBOL para C. Você pode usar esse RAM como ponto de início para seu próprio RAM escrito em COBOL, mas o RAM COBOL de amostra fornecido não deve ser usado em um ambiente de produção.
Os RAMs desenvolvidos em C implementam as funções de API do RAM CARMA, como initRAM ou getMembers. Os RAMs desenvolvidos em COBOL implementam cada uma dessas funções como programas COBOL individuais (chamados programas de função do RAM). No tempo de compilação, o código de origem de cada programa é concatenado e compilado em uma única DLL. Cada ID do programa será exportado para um deck paralelo de definição se a DLL estiver compilada para um PDS. O ID do programa de cada programa de função do RAM deve corresponder ao nome da função do RAM implementada por esse programa.
PROGRAM-ID. 'getInstances'.
Em um programa de função do RAM COBOL, a seção de ligação é usada para definir valores de parâmetro, estabelecer endereçabilidade para valores de ponteiro passados como parâmetros e referenciar o valor de número inteiro retornado pela função do RAM.
Cada parâmetro sendo passado à função do RAM deverá ser definido como um item de nível 77. Embora esses parâmetros não possam ser agrupados como itens de nível 77, recomenda-se que sejam definidos adjacentes entre si, na mesma sequência em que são passados ao programa (para maior clareza, localidade de referência e capacidade de leitura).
Por exemplo, você poderia usar o seguinte código para definir os parâmetros do programa de função do RAM getInstances:
77 ARG-RECORDS POINTER. 77 ARG-NUMRECS PIC S9(9) BINARY. 77 ARG-PARAMS POINTER. 77 ARG-RETURNS POINTER. 77 ARG-FILTER PIC X(256). 77 ARG-ERROR PIC X(256). 77 INT-RVAL PIC S9(9) BINARY.
Os itens de nível 77 também devem ser definidos para áreas referenciadas por ponteiros que não são dinâmicos no tamanho. Por exemplo, uma definição deve existir para referenciar o buffer de erros de 256 bytes. Use a seguinte definição para esse buffer de erros :
77 ERROR-BUFFER PIC X(256).
A seção de ligação também deve conter uma referência ao valor de número inteiro que está sendo retornado da função do RAM (o código de retorno). Defina esse número inteiro usando o seguinte código:
77 INT-RVAL PIC S9(9) BINARY.
A endereçabilidade para o código de retorno não precisa ser estabelecida. Pode simplesmente ser usada como se fosse definida na seção de armazenamento de funcionamento.
Os parâmetros devem ser estabelecidos com uma frase USING para que possam estar disponíveis ao programa COBOL. Como os parâmetros podem ser passados por referência ou valor, determine qual método é mais apropriado aos seus parâmetros dependendo das práticas de codificação em uso.
O seguinte exemplo de divisão de procedimento para a declaração getInstances ilustra como você pode designar os parâmetros a serem passados.
PROCEDURE DIVISION USING BY VALUE ARG-RECORDS BY REFERENCE ARG-NUMRECS BY VALUE ARG-PARAMS BY VALUE ARG-RETURNs BY REFERENCE ARG-FILTER BY REFERENCE ARG-ERROR RETURNING INT-RVAL.
Como cada função do RAM retorna um valor de número inteiro, a frase RETURNING é usada para especificar que um valor de número inteiro seja retornado do programa COBOL.
Como cada programa de função do RAM COBOL serve ao propósito de uma função do RAM C, cada programa de função do RAM deve ser finalizado com uma diretiva END PROGRAM. Ao compilar uma DLL do RAM COBOL, os programas de origem COBOL são fornecidos ao compilador de COBOL como uma série de instruções DD concatenadas. O não fornecimento das diretivas END PROGRAM fará com que os programas sejam tratados como aninhados, o que gerará mensagens de erro do compilador.
Os argumentos de função passados de um programa C para um programa de função do RAM COBOL devem ser manipulados de maneira apropriada ao método pelo qual eles estão sendo passados. Mais informações sobre esse tópico podem ser encontradas no guia: Language Environment Writing Interlanguage Communication Applications. Para obter informações específicas sobre como passar valores entre linguagens, consulte o Capítulo 4, Comunicação entre C e COBOL. Todos os exemplos nesta seção se referem ao comportamento no qual tipos de dados equivalentes devem ser definidos sem o uso de #pragma no programa C de chamada.
Há duas maneiras de usar parâmetros que foram passados de C. Os parâmetros podem ser incluídos na frase USING BY VALUE ou na frase USING BY REFERENCE do cabeçalho da divisão de procedimento.
Como regra geral, os argumentos de tipos de dados C básicos, como int, double, float ou long, que são passados na função C por valor devem ser recebidos com a frase BY VALUE na divisão de procedimento do programa COBOL. Para obter informações sobre cada tipo de dados C básico passado BY VALUE e como ele deve ser definido como item de seção de ligação, consulte o z/OS V1R8.0-V1R9.0 Language Environment Writing Interlanguage Communication Applications (SA22-7563-05), Capítulo 4 "Comunicação entre C e COBOL", Tabela 11. "Tipos de Dados Suportados Passados por Valor (Diretos) sem #pragma".
Os argumentos passados de C usando ponteiros (como sequências na forma de matrizes de caracteres) recebidos BY VALUE devem ser desreferenciados usando o operador SET. Como alternativa, os argumentos que usam ponteiros também podem ser recebidos com a frase da divisão de procedimento BY REFERENCE no programa COBOL de recebimento, desde que não exista possibilidade de o ponteiro passado ter um valor NULL. Mais informações sobre essa técnica podem ser encontradas em Evitando o Desreferenciamento (Recebendo Tipos de Dados C BY REFERENCE), localizado mais adiante nesta seção
Exemplo: Recebendo um número inteiro BY VALUE.
Nesse exemplo, o programa COBOL está recebendo um parâmetro definido como o tipo int em C.
Primeiro, uma entrada de seção de ligação deve ser definida para o valor de número inteiro recebido.
77 IN-INTEGER PIC S9(9) BINARY.
Em seguida, devemos incluir as informações corretas na instrução PROCEDURE DIVISION para tornar o número inteiro recebido disponível ao programa.
PROCEDURE DIVISION USING BY VALUE IN-INTEGER.
No programa COBOL, IN-INTEGER pode ser usado como se fosse qualquer outro item no armazenamento.
Exemplo 2: Recebendo Matrizes de Caracteres BY VALUE.
A maioria das funções de API do RAM C recebe uma matriz de caracteres C de 256 bytes preenchida com espaços chamada memberID. Em C, essa matriz é passada por referência usando um ponteiro.
Ao receber uma matriz de caracteres BY VALUE, o programa COBOL recebe uma cópia do ponteiro que aponta para o local de armazenamento que mantém os caracteres. Esse ponteiro deve ser desreferenciado manualmente para que a sequência possa ser usada no programa COBOL.
Defina o item na seção de ligação como POINTER.
77 IN-MEMBERID POINTER.
Você também deve definir um segundo item na seção de ligação para desreferenciar o ponteiro.
77 DEREFERENCED-MEMBERID PIC X(256)
Assegure-se de que PROCEDURE DIVISION receba o memberID adequadamente.
PROCEDURE DIVISION USING BY VALUE IN-MEMBERID
Em seguida, antes de trabalhar com o memberID, use o operador SET para desreferenciar IN-MEMBERID.
SET ADDRESS OF DEREFERENCED-MEMBERID TO IN-MEMBERID.
5. Agora DEREFERENCED-MEMBERID pode ser usado já que foi definido na seção de armazenamento de funcionamento:
MOVE ‘MEMBER1' TO DEREFERENCED-MEMBERID.
No recebimento de um parâmetro com a frase BY REFERENCE, o programa COBOL cuidará das operações de desreferenciamento desde que o item esteja definido corretamente na seção se ligação. Isso é útil para evitar operações de desreferenciamento, mas arriscado nos casos em que um ponteiro NULL possa ser passado no programa COBOL de recebimento.
Exemplo: Recebendo matrizes de caracteres BY REFERENCE.
Nesse exemplo, memberID será recebido pelo método BY REFERENCE do CARMA.
Primeiro, uma entrada de seção de ligação deve ser definida para corresponder à matriz de caracteres sendo passada.
77 IN-MEMBERID PIC X(256).
A instrução PROCEDURE DIVISION deve refletir à do item que está sendo recebido BY REFERENCE.
PROCEDURE DIVISION USING BY REFERENCE IN-MEMBERID.
IN-MEMBERID agora pode ser usado como se fosse qualquer outro item definido no armazenamento de funcionamento.
MOVE ‘MEMBER1' TO IN-MEMBERID.
As situações a seguir descrevem quando é apropriado ao programa COBOL receber parâmetros BY REFERENCE:
As situações a seguir descrevem quando é apropriado ao programa COBOL receber parâmetros BY VALUE:
Ao chamar funções C de DLL de dentro de COBOL, o método pelo qual os parâmetros são passados do programa COBOL deve corresponder cuidadosamente aos tipos de dados de cada parâmetro no protótipo da função C de recebimento. Isso é necessário a fim de evitar problemas como finalização anormal. A regra geral é que se uma função C receber um argumento que não seja um ponteiro, ele deve ser passado de COBOL usando a frase BY VALUE. Se o argumento for um ponteiro, deverá ser passado usando a frase BY REFERENCE.
Os tipos de dados C básicos localizados nos protótipos de função devem ser passados por valor do programa COBOL de chamada. No exemplo a seguir, é chamada uma função C que aceita dois argumentos que são tipos de dados C básicos do programa COBOL de chamada.
Protótipo de função C:
int callme(int a, double b);
Itens do armazenamento de funcionamento conforme devem ser definidos no programa COBOL de chamada:
01 FUNC-ARG1 PIC S9(9). 01 FUNC-ARG2 COMP-2. 01 RETVAL PIC S9(9) BINARY.
Um exemplo da instrução CALL no programa COBOL.
CALL "callme" USING BY VALUE FUNC-ARG1 FUNC-ARG2 RETURNING RETVAL.
As funções C frequentemente recebem argumentos para modificação de referência. O exemplo mais predominante disso é uma modificação de sequência no estilo C na qual uma matriz de caracteres é recebida por meio da cópia de um ponteiro para a sequência original. Os itens podem ser passados de COBOL para C para modificação de referência usando a frase BY REFERENCE dentro da instrução CALL. O exemplo a seguir demonstra essa situação.
Exemplo:
Protótipo de função C da função de recebimento:
int receiveString(char inString[256]);
Definições para o item do armazenamento de funcionamento que está sendo passado como um argumento e o valor de retorno:
01 THE-STRING PIC X(256). 01 RETVAL PIC S9(9) BINARY.
A instrução CALL no programa COBOL:
CALL "receiveString" USING BY REFERENCE THE-STRING RETURNING RETVAL.
Exemplo 2: Uma função C que recebe um ponteiro para um número inteiro do programa COBOL de chamada:
Protótipo de função C:
int changeInt(int * fromCOBOL);
Entrada do armazenamento de funcionamento no COBOL de chamada:
01 THE-INT PIC S9(9) BINARY. 01 RETVAL PIC S9(9) BINARY.
A instrução CALL no programa COBOL:
CALL "changeInt" USING BY REFERENCE THE-INT RETURNING RETVAL.
Para a maioria dos parâmetros passados aos programas de função do RAM COBOL, pouco código de desreferenciamento de ponteiro pode precisar ser implementado usando o operador SET. Por exemplo, a maior parte dos programas receberá um ponteiro para um buffer de 256 bytes para uma mensagem de erro detalhada. Para que você possa preencher esse buffer entretanto, ele deve ser desreferenciado usando o operador SET. Para itens menores, o desreferenciamento pode ser evitado com a frase USING BY REFERENCE.
Como exemplo, o código a seguir demonstra como estabelecer endereçabilidade ao buffer de erros. O ponteiro para o buffer de erros é passado por valor à divisão de procedimento para getInstances e definido na seção de ligação, conforme a seguir:
77 GIP-ERROR POINTER.
Mais tarde, na seção de ligação, o item de nível 77 é definido para desreferenciar e executar operações sobre o buffer de erros:
77 ERROR-BUFFER PIC X(256).
Em seguida, na divisão de procedimento, estabelece-se a endereçabilidade para o buffer de erros depois de verificar se GIP-ERROR não é NULL:
SET ADDRESS OF ERROR-BUFFER TO GIP-ERROR.
Agora, é possível tratar o buffer de erros como normalmente se faz com qualquer campo alfanumérico normal de 256 bytes. Nesse caso, o buffer de erros é uma sequência com terminação não NULL de 256 bytes.
Para ponteiros com diversos níveis de via indireta, as operações de desreferenciamento podem ser complicadas. O código COBOL para executar tais operações de desreferenciamento exigiriam diversos itens de nível 77 com uma operação SET para cada nível de via indireta. Para questões complicadas, estruturas alocadas dinamicamente são difíceis de acessar sem saber qual o tamanho máximo absoluto da estrutura.
Em vez de tentar operações de ponteiro complexas em COBOL, é altamente recomendável que um código dessa natureza seja implementado de forma modular usando a origem de COBOL para C. Atualmente, as funções são implementadas para alocação de memória e inserção e recuperação de dados em buffer de conteúdo. Você pode achar útil incluí-los nesse código conforme necessário e usá-los para operações mais complexas.
Como alternativa, as operações de ponteiro complexas podem ser executadas em COBOL, mas reduzem a capacidade de leitura e a sustentabilidade do código. Para lidar com estruturas dinâmicas, a aritmética de ponteiro é necessária. Para executar a aritmética de ponteiro, use redefinições. Para criar um ponteiro que possa ser manipulado por meio da aritmética de ponteiro, use um código semelhante ao seguinte na seção de armazenamento de funcionamento:
01 SOME-POINTER POINTER. 01 SOME-POINTER-MANIP REDEFINES SOME-POINTER. 05 ADD-TO-ME PIC S9(9) BINARY.
Após a definição do ponteiro, será possível manipulá-lo conforme necessário usando a versão redefinida. O código a seguir alteraria o ponteiro para apontar para a próxima estrutura em um chunk de memória alocado de forma contígua contendo diversas estruturas.
ADD SIZE-OF-STRUCTURE TO ADD-TO-ME. SET ADDRESS OF STRUCTURE TO SOME-POINTER.
Algumas funções do RAM, como extractMember e getAllMemberInfo, exigem que o RAM aloque memória. Essa memória é liberada mais tarde pelo CARMA, que usa a função C free para desalocar a memória. Por essa razão, um RAM implementado em COBOL deve usar a função C malloc ou o serviço do Language Environment CEEGTST para alocar memória. A origem de COBOL para C tem uma função C chamada CMALLOC para fornecer acesso a malloc de dentro do código COBOL. A função CMALLOC aceita como argumento um número inteiro que represente o número de bytes solicitado e retorne um ponteiro para a parte da memória que foi alocada. É responsabilidade do desenvolvedor do RAM assegurar-se de que o ponteiro não seja NULL antes de tentar usar a memória alocada.
A seguinte chamada de amostra para CMALLOC ilustra seu uso:
01 MALLOC-SIZE PIC S9(9) BINARY. 01 VOID-POINTER-RETURNED POINTER. MOVE 80 TO MALLOC-SIZE. CALL "CMALLOC" USING BY VALUE MALLOC-SIZE RETURNING VOID-POINTER-RETURNED.
O serviço de chamada do Language Environment CEEGTST também está disponível para adquirir armazenamento dinamicamente. Para obter mais informações sobre esse serviço e outros serviços fornecidos pelo Language Environment, consulte o z/OS V1R9.0 Language Environment Programming Reference (SA22-7562-09).
As variáveis globais que precisam ser compartilhadas entre programas de função do RAM podem ser declaradas como externas. O exemplo a seguir ilustra como declarar variáveis usando a palavra-chave EXTERNAL na entrada de armazenamento de funcionamento do programa de função initRAM:
01 SHARED-VARIABLES EXTERNAL. 05 LOG-FUNCTION-POINTER FUNCTION-POINTER. 05 TRACELEVEL PIC S9(9) BINARY. 05 FILE-POINTER POINTER. 05 LOCALE PIC X(8). 05 CODEPAGE PIC X(5).
No código de amostra anterior, as variáveis globais têm seus conjuntos de valores dentro da chamada para initRAM. Posteriormente, quando terminateRAM for chamado, esses valores serão exibidos para mostrar que são persistentes e compartilhados.
Esse tipo de definição deve ser usado para valores que precisam ser compartilhados entre chamadas para diferentes programas de função do RAM. Se um item de armazenamento de funcionamento só será acessado por um programa de função do RAM, não o declare como item externo. Os itens de armazenamento de funcionamento que não precisam ser modificados por outros programas de função do RAM não devem ser tornados externos.
O Custom Action Framework (CAF) permite que você expanda sobre os programas de função existentes do RAM COBOL, implementando novas ações customizadas que são designadas para atender às necessidades do cliente CARMA.
Ações customizadas podem ser criadas usando o arquivo de origem COBOL de amostra (CRACOB16, localizado na biblioteca de amostra) como um exemplo para implementar a função do RAM performAction. No programa de função do RAM performAction, use uma instrução EVALUATE para executar código baseado em ARG-ACTIONID seletivamente:
EVALUATE ARG-ACTIONID WHEN 119 CALL 'ESREVER' USING BY VALUE ARG-PARAMS ARG-RETURNS BY REFERENCE ARG-ERROR RETURNING RETCODE IF RETCODE NOT = 0 MOVE RETCODE TO INT-RVAL EXIT PROGRAM END-IF WHEN OTHER MOVE RC-UNSUPPORTED TO INT-RVAL EXIT PROGRAM END-EVALUATE.
Os parâmetros customizados podem ser recuperados por meio de duas operações de desreferenciamento. Depois de assegurar-se de que o ponteiro passado ao programa do RAM não é NULL, estabeleça a endereçabilidade para a matriz de ponteiros. Em seguida, desreferencie cada ponteiro para acessar cada parâmetro customizado ao qual ele faz referência. O seguinte extrato da seção de ligação para o programa de função do RAM performAction descreve os campos conforme eles são definidos para lidar com dois parâmetros customizados:
77 PA-PARAMS POINTER. 01 PARAMS. 05 PARAM1 POINTER. 05 PARAM2 POINTER. 01 CUSTOM-PARAM1 PIC S9(9) BINARY. 01 CUSTOM-PARAM2 PIC X(8).
Estabeleça primeiro a endereçabilidade para a lista de ponteiros de parâmetros customizados usando o seguinte código:
SET ADDRESS OF PARAMS TO PA-PARAMS.
Em seguida, estabeleça a endereçabilidade para parâmetros individuais.
SET ADDRESS OF CUSTOM-PARAM1 TO PARAM1. SET ADDRESS OF CUSTOM-PARAM2 TO PARAM2.
Os parâmetros customizados agora podem ser usados como se fossem campos normais na seção de armazenamento de funcionamento. Além disso, supõe-se que a instrução de divisão de procedimento tenha especificado que PA-PARMS está sendo usado BY VALUE.
O acesso a valores de retorno customizados em um RAM COBOL requer mais cuidado do que ao lidar com parâmetros customizados. Para que retornos customizados sejam estabelecidos, uma série de etapas concisas deve ser seguida. O código a seguir descreve os itens da seção de ligação que são usados para referenciar uma lista de dois retornos customizados. Supõe-se que a instrução de divisão de procedimento tenha especificado que PA-PARMS está sendo usado BY VALUE:
77 PA-RETURNS POINTER. 01 RETURNS-LV2 POINTER. 01 RETURNS-LV3. 05 RETURN1 POINTER. 05 RETURN2 POINTER. 01 CUSTOM-RETURN1 PIC X(8). 01 CUSTOM-RETURN2 PIC S9(9) BINARY.
Comece desreferenciando o primeiro nível de via indireta:
SET ADDRESS OF RETURNS-LV2 TO PA-RETURNS.
Em seguida, aloque a memória necessária para a matriz de ponteiros para os parâmetros customizados:
COMPUTE MALLOC-SIZE = SIZE-OF-POINTER * NUM-CUSTOM-RETURNS END-COMPUTE. CALL "CMALLOC" USING BY VALUE MALLOC-SIZE RETURNING RETURN-POINTER.
Agora, configure o ponteiro de segundo nível para apontar para esse bloco de memória.
SET RETURNS-LV2 TO RETURN-POINTER.
Em seguida, estabeleça a endereçabilidade para a lista de ponteiros para os valores de retorno que você acabou de alocar:
SET ADDRESS OF RETURNS-LV3 TO RETURNS-LV2.
Aloque a memória necessária para os parâmetros customizados:
* Allocate space for 8 byte string MOVE 8 TO MALLOC-SIZE. CALL "CMALLOC" USING BY VALUE MALLOC-SIZE RETURNING RETURN1. *Allocate space for integer MOVE 4 TO MALLOC-SIZE. CALL "CMALLOC" USING BY VALUE MALLOC-SIZE RETURNING RETURN2.
Por último, estabeleça a endereçabilidade para os valores de retorno e configure-os adequadamente.
SET ADDRESS OF CUSTOM-RETURN1 TO RETURN1. SET ADDRESS OF CUSTOM-RETURN2 TO RETURN2. MOVE ‘COBOLRAM' TO CUSTOM-RETURN1. MOVE 42 TO CUSTOM-RETURN2.
Em uma documentação do CARMA, há referências a uma "DLL de utilitário" e uma "origem de utilitário COBOL para C". Existe a possibilidade de confusão entre esses dois itens.
O nome "DLL de utilitário" é uma denominação incorreta. A "DLL de utilitário" é um conjunto de código de origem C encontrada no membro CRASUTIL na biblioteca SFEKSAMP do CARMA. Nenhuma forma de DLL compilada dessa origem é fornecida. A origem é destinada a fornecer diversas funções de utilitário em C que podem ser compartilhadas por várias implementações do RAM. Essas funções implementam tarefas que os desenvolvedores do RAM podem com frequência precisar executar no código deles. Esse código é fornecido pela equipe de desenvolvimento do CARMA para facilitar o processo de desenvolvimento do RAM. É possível compilar a origem como uma DLL, ou como código de objeto e incluí-la no processo de vinculação de qualquer RAM. Em qualquer dos dois casos, o código destina-se a ser compilado com as opções do compilador para produzir código DLL (por exemplo: RENT,DLL). Na criação dos RAMs de amostra fornecidos com o CARMA, o código do objeto de utilitário foi vinculado ao módulo final.
A outra origem de utilitário fornecida, COBOL para C, também é código C encontrado no membro CRACOBC1 da biblioteca SFEKSAMP. Essa origem é fornecida como um conjunto de funções C acessíveis aos desenvolvedores do RAM COBOL para simplificar tarefas que são complicadas de implementar em COBOL. As funções fornecidas também tornam possível acessar o log do CARMA, que é difícil em COBOL devido à especificação da API do RAM CARMA para o formato da função initRAM.
A "DLL de utilitário" e o "utilitário COBOL para C" são fornecidos aos desenvolvedores como código de amostra não suportado com o objetivo de simplificar a tarefa de desenvolvimento do RAM. Os desenvolvedores de C provavelmente só considerarão o uso da "DLL de utilitário" para desenvolver um RAM, e os desenvolvedores de COBOL deverão considerar utilizar ambos para simplificar o processo de desenvolvimento.
Há diversas técnicas e práticas de codificação disponíveis para facilitar o desenvolvimento do RAM COBOL.
O verbo DISPLAY pode ser usado para inspecionar os valores de variáveis de programa, parâmetros sendo passados e buffers sendo preenchidos. Além disso, as instruções DISPLAY podem ser muito úteis se inseridas para rastrear o caminho de execução. O mais importante é observar que os valores exibidos para ponteiros são mostrados em decimal, não em hexadecimal. A saída do uso do verbo DISPLAY será exibida na tarefa em spool do CARMA.
A tentativa de desreferenciar um ponteiro NULL quase certamente resultará em uma exceção de proteção. Isso efetivamente resultará não só na finalização do RAM, mas também do CARMA. Para evitar essa finalização anormal, todos os valores de ponteiro deverão ser verificados em busca de valores NULL. É fornecida documentação adicional sobre ponteiros e verificação de valores NULL no Enterprise COBOL for z/OS Language Reference.
Por convenção, STOP RUN é usado para finalizar a execução de um programa escrito puramente em COBOL. Entretanto, codificar STOP RUN em um RAM COBOL finalizará o CARMA e o RAM COBOL. É recomendável evitar STOP RUN, a menos que as circunstâncias exijam esse tipo de comportamento. Use EXIT PROGRAM em vez de STOP RUN para sair da execução do RAM COBOL e retornar ao processamento do CARMA.
O Custom Action Framework (CAF) é usado pelos desenvolvedores do RAM para descrever para os clientes CARMA como suas APIs do RAM diferem da API do RAM padrão. O CAF permite que uma API do RAM defina as seguintes diferenças entre sua API e a API do RAM padrão:
Essas diferenças são definidas usando as informações do CAF. As informações do CAF podem ser consideradas um contrato entre um RAM e os clientes CARMA que usam esse RAM; é garantido que o RAM será executado corretamente desde que os clientes CARMA sigam as informações do CAF do RAM. Antes de tentar definir as informações do CAF de um RAM, convém criar um modelo conceitual das informações do CAF do RAM. Isso ajudará você a planejar como definirá as informações do CAF dos RAMs nos clusters do VSAM do CARMA. Este capítulo fornece um exemplo prático de como criar tal modelo para um RAM e como definir então as informações do CAF para o RAM usando esse modelo.
Para poder seguir o exemplo, você deve entender primeiro os tipos de objeto básicos do CAF. O modelo de exemplo do RAM foi projetado usando esses objetos.
Há cinco tipos de objetos usados nas informações de CAF: RAMs, parâmetros, valores de retorno, ações e campos.
Os RAMs fornecem ao CARMA acesso a SCMs específicos. As informações do CAF para o RAM incluem as seguintes:
Parâmetros são valores passados a uma ação do cliente CARMA. Eles são definidos por RAM; assim, uma vez definido um parâmetro, seu ID pode ser usado na lista de parâmetros de qualquer ação definida para esse RAM. Isso pode ser útil se muitas das ações de um RAM precisarem dos mesmos parâmetros.
As informações do CAF para o RAM incluirão as seguintes informações sobre cada parâmetro.
Tipo de Parâmetro | Instruções de Especificação |
---|---|
int | Arbitrário (esse valor não importa) |
long | Arbitrário (esse valor não importa) |
double | A precisão do parâmetro |
string | A largura do campo do parâmetro |
Valores de retorno são o resultado de uma ação chamada pelo CARMA. Eles são definidos por RAM; assim, uma vez definido um valor de retorno, seu ID pode ser usado na lista de valores de retorno de qualquer ação definida para esse RAM. Isso pode ser útil se muitas das ações de um RAM precisarem dos mesmos valores de retorno.
As informações do CAF para o RAM incluirão as seguintes informações sobre cada valor de retorno.
Tipo de Parâmetro | Instruções de Especificação |
---|---|
int | Arbitrário (esse valor não importa) |
long | Arbitrário (esse valor não importa) |
double | A precisão do valor de retorno |
string | A largura do campo do valor de retorno |
Todos os RAMs têm um conjunto padrão de ações definidas na API do RAM. Você pode usar o CAF para modificar essas ações padrão para usar parâmetros de entrada adicionais, para usar valores de retorno adicionais ou para serem ocultadas do CARMA (desativando essencialmente as ações).
Você também pode declarar novas ações ("customizadas"). Cada ação customizada declarada tem um ID designado (chamado seu ID de ação). Quando um cliente CARMA tentar chamar uma ação customizada em um RAM, o CARMA chamará primeiro a função performAction do RAM, passando o ID de ação (fornecido pelo cliente CARMA) da ação customizada como um parâmetro. A função performAction deve então tentar chamar a função para a ação customizada com o ID de ação especificado.
As informações do CAF para o RAM incluirão as seguintes informações sobre cada ação (para ações desativadas, apenas os IDs do RAM e de ação são necessários):
Campos descrevem metadados de interesse específicos dos usuários. As informações do CAF para Campos incluem as seguintes:
Suponha que desejamos criar um RAM denominado RAM SAMP, capaz de acessar uma solução SCM denominada SCM de Amostra. Suponha que o SCM de Amostra opera de uma maneira que faz com que o RAM SAMP tenha as seguintes diferenças de um RAM CARMA padrão:
Para suportar totalmente a funcionalidade do SCM de Amostra, usaremos o CAF para customizar a API do RAM. Precisaríamos criar três novas ações customizadas (para as operações bloquear instância, remover sinalizador e concatenar) e substituir duas das ações padrão (bloquear e efetuar registro de saída).
Suponha que para esse exemplo nós estejamos desenvolvendo a primeira versão do RAM SAMP (versão 1.0), que está sendo projetado para acessar o SCM de Amostra versão 1.4 e trabalhar com o CARMA versão 2.5, e que será escrito em C e compilado em uma DLL chamada SAMPRAM. Para esse exemplo, designaremos ao RAM SAMP um ID do RAM igual a 1.
Nós agora temos todas as informações sobre o RAM necessárias para o modelo de RAM SAM (consulte RAM). A tabela a seguir resume essas informações:
Nome | RAM SAMP |
Descrição | Fornece ao CARMA acesso às instâncias do SCM de Amostra |
ID do RAM | 1 |
Linguagem de Programação | C |
Nome da DLL do RAM | SAMPRAM |
Versão | 1.0 |
Versão do Repositório | 1.4 |
Versão do CARMA | 2.5 |
Neste momento, podemos achar útil tabular as informações (conforme descrito em Ações) para todas as ações que precisam ser criadas ou substituídas. As tabelas a seguir resumem essas informações. Observe que o ID da ação de bloqueio corresponde ao ID da ação de bloqueio padrão (consulte Apêndice B. IDs de Ação) para assegurar-se de que a ação de bloqueio original seja substituída. A ação de registro de saída ativado da mesma forma tem um ID designado que corresponde à ação de registro de saída padrão.
Nome | Bloquear instância |
Descrição | Bloqueia uma instância no SCM |
ID da Ação | 100 |
ID do RAM | 1 |
Lista de Parâmetros |
ID da Instância Motivo |
Lista de Valores de Retorno |
Código de retorno Tipo de bloqueio |
Nome | Remover sinalizador |
Descrição | Remove um sinalizador de um membro no SCM |
ID da Ação | 101 |
ID do RAM | 1 |
Lista de Parâmetros |
ID da Instância ID do Membro Motivo |
Lista de Valores de Retorno | Código de retorno |
Nome | Concatenar |
Descrição | Concatena o conteúdo de dois membros no SCM |
ID da Ação | 102 |
ID do RAM | 1 |
Lista de Parâmetros |
ID da instância de destino ID do membro de destino ID da instância-alvo ID do membro-alvo |
Lista de Valores de Retorno |
Código de retorno Novo ID da instância Novo ID do membro |
Nome | Lock |
Descrição | |
ID da Ação | 10 |
ID do RAM | 1 |
Lista de Parâmetros |
ID da Instância ID do membro |
Lista de Valores de Retorno |
Código de retorno Tipo de bloqueio |
Nome | Efetuar o registro de saída |
Descrição | (Desativado) |
ID da Ação | 13 |
ID do RAM | 1 |
Lista de Parâmetros | (Desativado) |
Lista de Valores de Retorno |
Como os IDs da instância e do membro são passados por padrão a todas as ações (consulte a descrição de "Lista de parâmetros" em Ações), somente três parâmetros adicionais precisam ser definidos para as ações customizadas (bloquear instância, remover sinalizador e concatenar) e a ação de bloqueio: motivo, ID da instância-alvo e ID do membro-alvo. Para a ação concatenar, podemos mapear o ID da instância de destino e o ID do membro de destino respectivamente para o ID da instância e o ID do membro de parâmetros padrão.
Podemos agora listar todos os parâmetros necessários ao modelo de RAM SAMP. As tabelas a seguir resumem essas informações. Observe que são designados aos parâmetros ID sequenciais, começando com 0 para o primeiro parâmetro.
Nome | Motivo |
Descrição | Motivo pelo qual a ação deve ser executada |
ID do parâmetro | 0 |
ID do RAM | 1 |
Tipo | String |
Comprimento | 30 |
Constante | Não |
Valor-padrão | Nenhum |
Prompt | Por que você está solicitando que a ação seja executada? |
Nome | ID da instância-alvo |
Descrição | ID da instância que contém o membro cujo conteúdo deve ser anexado ao final do membro determinado |
ID do parâmetro | 1 |
ID do RAM | 1 |
Tipo | String |
Comprimento | 15 |
Constante | Não |
Valor-padrão | Nenhum |
Prompt | Qual instância contém o membro que você deseja concatenar com o membro selecionado? |
Nome | ID do membro-alvo |
Descrição | ID do membro cujo conteúdo deve ser anexado ao final do membro determinado |
ID do parâmetro | 1 |
ID do RAM | 1 |
Tipo | String |
Comprimento | 30 |
Constante | Não |
Valor-padrão | Nenhum |
Prompt | O conteúdo de qual membro você deseja anexar ao final do membro selecionado? |
Somente três valores de retorno adicionais precisam ser definidos para o RAM SAMP, porque o código de retorno já é retornado por padrão (consulte a descrição de "Lista de valores de retorno" em Ações). As tabelas a seguir resumem as informações de valor de retorno necessárias para o modelo de RAM SAM. Novamente, observe que são designados aos valores de retorno ID sequenciais, começando com 0 para o primeiro valor de retorno.
Nome | Tipo de bloqueio |
Descrição | O tipo de bloqueio sendo aplicado ao membro |
ID do Valor de Retorno | 0 |
ID do RAM | 1 |
Tipo | Int |
Comprimento | 4 |
Nome | Novo ID da instância |
Descrição | A instância na qual os resultados da ação foram colocados |
ID do Valor de Retorno | 1 |
ID do RAM | 1 |
Tipo | String |
Comprimento | 30 |
Nome | Novo ID do membro |
Descrição | O membro que contém os resultados da ação |
ID do Valor de Retorno | 1 |
ID do RAM | 1 |
Tipo | String |
Comprimento | 30 |
Com todas as informações necessárias para definir o RAM SAMP para o CAF perfeitamente tabulado, podemos representar as informações visualmente. A Figura 10 ilustra o relacionamento entre as ações, os parâmetros e os valores de retorno usados no RAM SAMP. Antes de configurar os clusters para um RAM, você pode achar útil desenvolver um diagrama semelhante.
Agora que temos um modelo para o RAM SAMP, podemos facilmente definir as informações do CAF do RAM SAMP. Para fazer isso, é necessário primeiro entender onde e como as informações do CAF são armazenadas. Há dois clusters do VSAM sequenciados por chave do CAF que armazenam todas as informações do CAF: CRADEF e CRASTRS. Conforme o CARMA é carregado, ele descobre os RAMs disponíveis a ele (bem como suas ações, parâmetros e valores de retorno correspondentes) lendo o CRADEF, que contém informações sobre os recursos dos RAMs disponíveis. Conforme necessário, o CARMA tenta determinar se o idioma preferencial de um usuário está disponível para um determinado RAM verificando o CRASTRS, que contém informações específicas de código de idioma para os RAMs.
O CRADEF armazena todos os dados do CAF independentes de idioma (dados que não precisam ser traduzidos de um código de idioma para outro), usando caracteres em inglês da página de códigos 00037. Ele contém registros para cada tipo de objeto do CAF (RAMs, ações, parâmetros e valores de retorno), usando uma largura de registro de 1032 bytes. Entretanto, somente registros de ação podem de fato usar todos os 1032 bytes; os outros tipos de registro apenas preenchem os bytes não usados com espaços. O CRADEF usa uma chave de 8 bytes e reserva os 1024 bytes restantes para dados. A Tabela A resume a composição de um registro genérico no CRADEF:
Registro de 1032 Bytes | |
---|---|
(8 bytes) Chave |
(1024 bytes) Dados |
As chaves de registro CRADEF são compostas dos seguintes campos:
A tabela a seguir resume o formato de chave CRADEF.
Chave de 8 Bytes | |||
---|---|---|---|
(1 byte) Tipo |
(2 bytes) ID do RAM |
(3 bytes) ID Secundário |
(2 bytes) Não usado |
O restante dos bytes em cada registro é usado para dados do registro. Esses 1024 bytes contêm diferentes campos dependendo do tipo de registro:
A tabela a seguir resume os formatos de dados CRADEF para cada tipo de objeto do CAF.
Tipo | Dados de 1024 Bytes | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
R |
(8 bytes) Versão do RAM |
(8 bytes) Linguagem de Programação |
(8 bytes) Versão do Repositório |
(8 bytes) Versão do CARMA |
(8 bytes) Nome da DLL |
|||||
A |
(* bytes) Lista de IDs de Parâmetro |
(1 byte) Barra Vertical Separadora de Lista |
(* bytes) Lista de IDs de Valor de Retorno |
|||||||
D |
(1024 bytes) Não usado |
|||||||||
P |
(16 bytes) Tipo |
(16 bytes) Comprimento |
(1 byte) Constante |
|||||||
T |
(16 bytes) Tipo |
(16 bytes) Comprimento |
||||||||
F |
(64 bytes) Chave de Metadados |
|||||||||
I |
(1024 bytes) Identificador |
O CRASTRS armazena todos os dados do CAF dependentes de idioma (dados que precisam ser traduzidos de um código de idioma para outro, como descrições e mensagens). Os idiomas são indexados no cluster do VSAM com base em um código de idioma de oito caracteres (por exemplo, "EN_US " ou "FR_FR ") e uma página de código de cinco caracteres (por exemplo, "00037"). Como um cliente CARMA inicializa o CARMA, o cliente fornece ao CARMA um código de idioma e a página de códigos, que o CARMA tenta localizar no CRASTRS. Se a combinação especificada de código de idioma e página de código não estiver disponível no ambiente do CARMA, o CARMA usará o código de idioma padrão ("EN_US") e a página de códigos ("00037") e retornará um erro ao cliente.
Quando um cliente solicitar a lista de RAMs disponíveis, o CARMA fará referência ao CRASTRS para tentar compor uma lista dos RAMs que estão disponíveis no código do idioma e na página de códigos do cliente solicitados. Por convenção, se um registro do RAM estiver disponível em um determinado código de idioma, espera-se que suas ações, parâmetros e valores de retorno também estejam disponíveis nesse mesmo código de idioma.
O CRASTRS permite sequências de um comprimento não fixo (anteriormente, o CRASTRS usava uma largura de registro de 2101 bytes compostos por uma chave de 21 bytes e 2080 bytes para dados). As sequências são separadas por um único caractere não de espaço usado para delimitar sequências em todo o arquivo. Você pode definir o caractere delimitador quando configura o arquivo CRASTRS. Se você não defini-lo, o padrão será o caractere de tabulação horizontal (0x05 em EBCDIC)
Se o CRASTRS contiver um registro com a chave "000000000000000000000" (vinte e um zeros), o CARMA usará o formato de sequência não fixo no arquivo inteiro do VSAM. Se o CRASTRS não contiver essa chave de registro, o CARMA usará o formato de sequência de largura fixa no arquivo inteiro do VSAM.
As chaves de registro CRASTRS são compostas pelos seguintes campos:
A tabela a seguir resume o formato de chave CRASTRS.
Chave de 21 Bytes | ||
---|---|---|
(8 bytes) Código do Idioma |
(5 bytes) Página de Códigos |
(8 bytes) Chave de Registro |
O restante do registro é usado para dados do registro. Os dados do registro contêm diferentes campos dependendo do tipo de registro. Nas versões anteriores, esses dados estavam limitados a 2080 bytes. Quando CRASTRS contém um registro com a chave "000000000000000000000" (vinte e um zeros), esse limite não se aplica mais.
Todas as informações na seção de dados devem estar no código de idioma e na página de códigos especificados na chave. A tabela a seguir resume os formatos de dados CRASTRS para cada tipo de objeto do CAF.
Tipo | Data | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
A R T |
Nome |
Descrição |
||||||||||
P |
Nome |
Valor-padrão |
Prompt |
Descrição |
||||||||
F |
Nome |
Valor-padrão |
Descrição |
Construindo com base no exemplo anterior de RAM SAMP, é possível definir registros para o RAM SAMP no CRADEF conforme mostrado na tabela a seguir.
Tecla | Data | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Um | 01 | 010 | 000 | | | |||||||||
Um | 01 | 100 | 000 | | | 000 | ||||||||
Um | 01 | 101 | | | 000 | |||||||||
Um | 01 | 102 | 001,002 | | | 001,002 | ||||||||
D | 01 | 013 | |||||||||||
P | 01 | 000 | STRING | 30 | N | ||||||||
P | 01 | 001 | STRING | 15 | N | ||||||||
P | 01 | 002 | STRING | 30 | N | ||||||||
R | 01 | 000 | 1.0 | C | 1.4 | 2.5 | SAMPRAM | ||||||
T | 01 | 000 | INT | 4 | |||||||||
T | 01 | 001 | STRING | 30 | |||||||||
T | 01 | 002 | STRING | 30 |
Consulte FEK.SFEKVSM2(CRAINIT) para obter um exemplo do formato de coluna adequado. Esse conjunto de dados sequenciais é usado para inicializar o CRADEF durante a instalação do CARMA. Inicialmente, ele continha registros para o RAM PDS de amostra, o RAM SCLM de amostra e o RAM Esqueleto. Entretanto, dependendo da configuração do host, FEK.SFEKVSM2(CRAINIT) poderá ter sido modificado se RAMs foram incluídos ou removidos do ambiente do CARMA.
Para incluir um RAM no cluster CRADEF, inclua os registros dele em FEK.SFEKVSM2(CRAINIT). Assegure-se de que todas as chaves de registro estejam em ordem alfanumérica para que a operação REPROed do conjunto de dados possa ser bem-sucedida. Use o script da JCL localizado em FEK.#CUST.JCL(CRA$VDEF) para REPRO FEK.SFEKVSM2(CRAINIT).
É necessário agora definir os registros específicos do código de idioma no CRASTRS. Suponha que o RAM SAMP precise de suporte para inglês e português do Brasil. É possível definir registros para o RAM SAMP no CRASTRS conforme mostrado na tabela a seguir.
Chave | Dados | |||||
---|---|---|---|---|---|---|
EN_US | 00037 | A01010 | ||||
EN_US | 00037 | A01100 | Bloquear Instância | Bloqueia a instância | ||
EN_US | 00037 | A01101 | Remover sinalizador | Remove um sinalizador | ||
EN_US | 00037 | A01102 | Concatenar | Concatena dois conjuntos de dados | ||
EN_US | 00037 | P01000 | Razão | Por que não? | Por que você deseja que eu execute a ação? | A razão para executar a ação |
EN_US | 00037 | P01001 | ID da Instância-alvo | MyInstance | Em qual instância o membro está localizado? | A instância contendo o membro a ser concatenado |
EN_US | 00037 | P01002 | ID do Membro-alvo | MyMember | Que membro você gostaria de concatenar? | O membro a ser concatenado |
EN_US | 00037 | R01000 | RAM de amostra | Um RAM de exemplo | ||
EN_US | 00037 | T01000 | Tipo de Bloqueio | O tipo de bloqueio que o SCM coloca no membro | ||
EN_US | 00037 | T01001 | Novo ID da Instância | O ID da instância de concatenação | ||
EN_US | 00037 | T01002 | Novo ID do Membro | O ID do membro da concatenação | ||
PT_BR | 01047 | A01010 | ||||
PT_BR | 01047 | A01100 | Bloquear Instncia | Bloqueia a instncia | ||
PT_BR | 01047 | A01101 | Tirar sinalizador | Remove um sinalizador | ||
PT_BR | 01047 | A01102 | Concatenar | Concatena dois conjuntos de dados | ||
PT_BR | 01047 | P01000 | Motivo | Por que nÆo? | Por que você deseja que eu execute a aÆo? | O motivo para executar a aÆo |
PT_BR | 01047 | P01001 | ID de Instncia de Destino | MyInstance | Em qual instncia o membro está localizado? | A instncia que cont‚m o membro a ser concatenado |
PT_BR | 01047 | P01002 | ID do Membro de Destino | MyMember | Qual membro você deseja concatenar? | O membro a ser concatenado |
PT_BR | 01047 | R01000 | RAM de Amostra | Um RAM de exemplo | ||
PT_BR | 01047 | T01000 | Tipo de Bloqueio | O tipo de bloqueio que SCM coloca no membro | ||
PT_BR | 01047 | T01001 | Novo ID de Instncia | O ID de instncia de concatenaÆo | ||
PT_BR | 01047 | T01002 | Novo ID do Membro | O ID do membro de concatenaÆo |
Consulte FEK.SFEKVSM2(CRASINIT) para obter um exemplo do formato de coluna adequado. Esse conjunto de dados sequenciais é usado para inicializar o CRASTRS durante a instalação do CARMA. Como FEK.SFEKVSM2(CRAINIT), inicialmente, ele continha as sequências para o RAM PDS de amostra, o RAM SCLM de amostra e o RAM Esqueleto. Dependendo da configuração do host, FEK.SFEKVSM2(CRASINIT) poderá também ter sido modificado se RAMs foram incluídos ou removidos do ambiente do CARMA.
Para incluir um RAM no cluster CRASTRS, inclua os registros dele em FEK.SFEKVSM2(CRASINIT). Assegure-se de que todas as chaves de registro estejam em ordem alfanumérica para que a operação REPROed do conjunto de dados possa ser bem-sucedida. Use o script da JCL localizado em FEK.#CUST.JCL(CRA$VSTR) para REPRO FEK.SFEKVSM2(CRASINIT).
Ao editar clusters do VSAM, assegure-se de que nenhum cliente esteja acessando o CARMA. O CARMA pode apresentar um comportamento anormal se o cluster do VSAM for alterado enquanto ele está operando. É recomendável que apenas administradores de sistema e desenvolvedores de RAM tenham acesso de gravação aos clusters do VSAM, mas que todos os usuários tenham acesso de leitura.
Os clientes CARMA podem ser projetados para trabalhar especificamente com um RAM, podem fornecer uma interface genérica para qualquer RAM a ser usado ou podem fazer uma combinação dos dois. Um bom exemplo de cliente genérico que pode também ser modificado para trabalhar especificamente com determinados RAMs é o IBM Rational Developer for System z. O Rational Developer foi projetado para suportar as funções básicas que todos os RAMs têm em comum; por isso, um RAM que se ajuste perfeitamente à especificação da API do RAM CARMA funcionaria com o Rational Developer sem complicações. O Rational Developer fornece também pontos de extensão com os quais os desenvolvedores do RAM podem customizar o cliente para seus RAM(s). Por outro lado, um cliente não interativo e extremamente específico poderia ser escrito para apenas executar operações de manutenção por meio de um RAM.
Os clientes CARMA podem usar algumas ou todas as funções básicas da API do CARMA. As únicas funções que é obrigatório implementar são initCarma, initRAM e terminateCarma. terminateRAM não é obrigatório porque terminateCarma cuidará da limpeza dos RAMs se for chamado e o CARMA ainda tiver RAMs carregados. Entretanto, deve ser tomado um cuidado especial com a memória que é passada de/para o CARMA. Muitas vezes, o RAM alocará memória que o cliente é obrigado a liberar. Leia Armazenando Resultados para Uso Posterior e Alocação de Memória cuidadosamente até o fim, visto que fugas de memória e finalização anormal do programa podem facilmente resultar do não seguimento das recomendações sobre a manipulação de memória de cada função.
Os clientes CARMA podem incluir o deck paralelo da DLL do CARMA durante a compilação (fazendo com que a DLL do CARMA seja carregada implicitamente) ou podem ser compilados sem o deck paralelo (fazendo com que a DLL do CARMA seja carregada explicitamente). O cliente de exemplo (CRACLISA na biblioteca de amostra) carrega implicitamente a DLL do CARMA. O código JCL para compilar um cliente que carregará implicitamente a DLL do CARMA está no arquivo de amostra denominado CRACLICM.
Ao executar um cliente CARMA, você deve assegurar-se de que o CARMA e todos os RAMs dele tenham os recursos que eles precisam disponíveis a eles. O CARMA requer acesso ao seu cluster de mensagens do VSAM (CRAMSG), aos cluster de CAF do VSAM (CRADEF e CRASTRS) e ao PDS que contém os RAMs. Navegue na JCL usada para executar clientes (CRACLIRN, localizada na biblioteca de amostra) para ver as instruções DD que o CARMA requer (CRASTRS, CRAMSG e CRADEF) e como a DLL do CARMA e o PDS que contém todos os RAMs são incluídos na instrução STEPLIB DD. Os RAMs devem documentar todos os recursos que eles precisam. Por exemplo, o RAM PDS de amostra e o RAM SCLM de amostra exigem cada um que um cluster de mensagens esteja disponível; por isso, a JCL usada para executar o cliente deve ser modificada para que o RAM possa acessar esses recursos. Não fornecer ao CARMA ou aos RAMs o acesso a seus recursos requeridos pode resultar em comportamento anormal.
Ao fornecer recursos aos RAMs, as bibliotecas de mensagens do TSO/ISPF também devem ser consideradas. Os RAMs poderão usar as mensagens do TSO/ISPF se erros ocorrerem. Por padrão, a JCL usada para executar um cliente fornecerá aos RAMs a versão em inglês (página de códigos 00037) dessas mensagens. A JCL deverá ser editada apropriadamente se o RAM precisar retornar as mensagens do TSO/ISPF ao cliente em um idioma diferente.
O cliente deve armazenar os resultados da maioria das operações executadas durante uma sessão do CARMA, especialmente os resultados das funções de navegação, como getMembers e getInstances. Todas as instâncias, membros simples e contêineres têm um ID e um nome de exibição. O nome de exibição é o que o cliente deve mostrar ao usuário. O nome de exibição para uma entidade deve ser fornecido no contexto da instância dessa entidade e, se aplicável, a todos os contêineres-pai necessários para atingir essa entidade. O ID define a entidade para o RAM exclusivamente. Por exemplo, o ID da entidade pode simplesmente conter seu caminho absoluto. Como alternativa, o RAM pode usar uma função hash para obter do ID o caminho absoluto da entidade. O ID deve ser armazenado pelo cliente para que possa ser novamente passado ao RAM conforme necessário. Por exemplo, um usuário pode obter uma lista de membros em uma instância e, em seguida, verificar se um desses membros é um contêiner.
As outras partes dos dados que podem precisar ser armazenadas pelo cliente (se não forem conhecidas ainda) são chaves de metadados, informações de CAF do RAM e nomes. As informações de CAF do RAM são requeridas por virtualmente cada função que usa um RAM para executar uma operação. As informações de CAF que são obrigatórios podem ser tão simples quanto o ID do RAM pelo qual a ação deve ser executada.
Em sua maioria, as funções do RAM são estruturas predefinidas para passar informações de volta ao CARMA e depois ao RAM. Algumas estruturas passam informações sobre um RAM, enquanto outras são usadas para comunicação de/para o RAM. É responsabilidade do Cliente liberar memória usada por essas estruturas, incluindo qualquer matriz de caracteres de comprimento indefinido. Essas matrizes terão terminação nula no estilo C normal.
Ao executar uma ação com relação ao CARMA, o cliente deve ver se a respectiva estrutura Action da ação existe para o RAM com o qual está sendo trabalhado. Se a resposta for sim, deve-se usar a estrutura Action e as estruturas Parameter relacionadas para chamar a ação. Após a ação ser concluída, o cliente deve usar as estruturas returnValue relacionadas à ação chamada para analisar adequadamente a resposta da ação.
As estruturas aplicáveis são resumidas nas tabelas a seguir. Essas estruturas estão disponíveis no arquivo de cabeçalho CRADSDEF localizado na biblioteca de amostra. Essas estruturas quase sempre são alocadas pelo RAM; por isso, é improvável que o cliente ainda tenha de inicializar qualquer um de seus buffers. Entretanto, o cliente terá de liberar qualquer memória alocada pelo RAM.
As estruturas RAMRecord e RAMRecord2 consistem em um ID do RAM de número inteiro, um campo de caractere name de 16 bytes e diversos outros campos de caractere que descrevem o RAM.
Campo | Descrição | |
---|---|---|
RAMRecord | RAMRecord2 | |
int id | int id | ID exclusivo para descrever o RAM |
char name[16] | char* name | Nome de exibição |
char version[8] | char* version | Versão do RAM |
char reposLevel[8] | char* reposLevel | O nível do SCM que o RAM acessa. |
char language[8] | char* language | Linguagem na qual o RAM é escrito |
char CRALevel[8] | char* CRALevel | O nível do CARMA ao qual o RAM foi designado. |
char moduleName[8] | char* moduleName | Nome do módulo do RAM a ser carregado |
char description[2048] | char* description | Exibido como uma descrição do RAM pelo cliente. |
não-aplicável | char* uniqueId | Especifica um ID do RAM exclusivo. |
A estrutura Descriptor consiste em um campo de caractere name de 64 bytes e um campo de caractere ID de 256 bytes. É usado para descrever instâncias, contêineres e membros simples.
Campo | Descrição |
---|---|
char id[256] | ID exclusivo para descrever a entidade |
char name[64] | Nome de exibição |
A estrutura DescriptorWithInfo consiste em um campo de caractere name de 64 bytes e um campo de caractere ID de 256 bytes, um número inteiro que armazena o número de pares de valores de chaves e uma matriz de pares de valores de chaves contendo informações de metadados.
Campo | Descrição |
---|---|
char id[256] | ID exclusivo para descrever a entidade |
char name[64] | Nome de exibição |
int infoCount | O número de pares de valores de chaves na matriz de informações |
KeyValPair* info | Uma matriz contendo informações de metadados na forma de pares de valores de chaves. |
A estrutura MemberDescriptorWithInfo consiste em um campo de caractere name de 64 bytes e um campo de caractere ID de 256 bytes, um número inteiro que armazena o número de pares de valores de chaves e uma matriz de pares de valores de chaves contendo informações de metadados, bem como um número inteiro indicando se o membro é um contêiner.
Campo | Descrição |
---|---|
char id[256] | ID exclusivo para descrever a entidade |
char name[64] | Nome de exibição |
int infoCount | O número de pares de valores de chaves na matriz de informações |
KeyValPair* info | Uma matriz contendo informações de metadados na forma de pares de valores de chaves. |
int isContainer | Um valor igual a 0 indica que o membro não é um contêiner. Um valor igual a 1 indica que ele é um contêiner. |
A estrutura KeyValPair consiste em um campo-chave de 64 bytes e um campo de valor de 256 bytes. É usado para pares de valores de chaves de metadados.
Campo | Descrição |
---|---|
char key[64] | Um índice |
char value[256] | Os dados |
As estruturas Action e Action2 consistem em um ID de número inteiro, um nome de 16 bytes, um ponteiro para uma matriz de números inteiros para armazenar os IDs dos parâmetros relacionados à ação, um número inteiro que armazena o número de parâmetros associados à ação, um ponteiro para uma matriz de números inteiros para armazenar os IDs dos valores de retorno relacionados à ação, um número inteiro que armazena o número de valores de retorno associados à ação e uma descrição de 1024 bytes.
Campo | Descrição | |
---|---|---|
Action | Action2 | |
int id | int id | Um identificador numérico para a ação entre 0 e 999. Os IDs de ação entre 0 e 79 substituem ações padrão, enquanto os IDs entre 100 e 999 definem ações customizadas. Os IDs de ação entre 80 e 99 são reservados para uso do CARMA. |
char name[16] | char* name | O nome da ação |
int* paramArr | int* paramArr | Uma lista dos IDs para os parâmetros que a ação usa |
int numParams | int numParams | O número de elementos na matriz paramArr |
int* returnArr | int* returnArr | Uma lista dos IDs para os valores de retorno que a ação retorna |
int numReturn | int numReturn | O número de elementos na matriz returnArr |
char description[1024] | char* description | Uma descrição curta da ação |
As estruturas Parameter e Parameter2 consistem em um ID de número inteiro, um nome de 16 bytes, um tipo de 16 bytes, um valor padrão de 16 bytes, um comprimento de número inteiro, um número inteiro especificando se ele é constante (um valor igual a 1 indica que é), um prompt de 1024 bytes e uma descrição de 1024 bytes.
Campo | Descrição | |
---|---|---|
Parameter | Parameter2 | |
int id | int id | Um identificador numérico para o parâmetro entre 0 e 999 |
char name[16] | char* name | O nome do parâmetro |
char type[16] | char* type | O tipo de dados do parâmetro ("INT", "LONG", "DOUBLE" ou "STRING") |
char defaultValue[16] | char* defaultValue | O valor padrão do parâmetro |
int length | int length | A precisão do parâmetro (se for do tipo "DOUBLE") ou a largura do campo do parâmetro (se for do tipo "STRING"). Se o parâmetro for de algum outro tipo, esse valor poderá ser ignorado. |
int isConstant | int isConstant | Se o parâmetro sempre conterá ou não o mesmo valor |
char prompt[1024] | char* prompt | O prompt que o cliente CARMA deverá exibir ao solicitar um valor para o parâmetro dos usuários |
char description[1024] | char* description | Uma descrição curta do parâmetro |
As estruturas returnValue e returnValue2 consistem em um ID de número inteiro, um nome de 16 bytes, um tipo de 16 bytes, um comprimento de número inteiro e uma descrição de 1024 bytes.
Campo | Descrição | |
---|---|---|
returnValue | returnValue2 | |
int id | int id | Um identificador numérico para o valor de retorno entre 0 e 999 |
char name[16] | char* name | O nome do valor de retorno |
char type[16] | char* type | O tipo de dados do valor de retorno ("INT", "LONG", "DOUBLE" ou "STRING") |
int length | int length | A precisão do valor de retorno (se for do tipo "DOUBLE") ou a largura do campo do valor de retorno (se for do tipo "STRING"). Se o valor de retorno for de algum outro tipo, esse valor poderá ser ignorado. |
char description[1024] | char* description | Uma descrição curta do valor de retorno |
As estruturas Field e Field2 consistem em um ID de número inteiro, uma chave de membro de 64 bytes, um nome de 128 bytes, um valor padrão de 256 bytes e uma descrição de 1024 bytes.
Campo | Descrição | |
---|---|---|
Campo | Field2 | |
int id | int id | Um identificador numérico para o valor de campo entre 0 e 999 |
char memberKey[64] | char* memberKey | A chave de metadados a ser fornecida à função getMemberInfo para o campo a ser exibido. |
char name[128] | char* name | O nome exibível localizado do campo. |
char defaultValue[256] | char* defaultValue | O valor exibível localizado do campo se nenhum valor for retornado por uma chamada para getMemberInfo. |
char description[1024] | char* description | Uma descrição exibível localizada dos metadados. |
O CARMA e os RAMs gravarão mensagens em um log por sessão do CARMA. Ao inicializar o CARMA, um nível de rastreio deve ser passado a ele. Os níveis de rastreio são mostrados na Tabela 3. A criação de log pode ser desativada enviando ao CARMA um nível de rastreio igual a -1.
Parâmetros customizados são passados ao RAM usando o parâmetro void** params. params é uma matriz de ponteiros void que apontam para variáveis de diversos tipos. A função getCAFData ou getCAFData2 retornará as informações de Estrutura de Ação Customizada para todas as funções do RAM. Chame esta antes de executar qualquer outra função do RAM para determinar quais parâmetros e valores de retorno customizados as funções do RAM usam. Os parâmetros customizados obrigatórios devem ser passados ao RAM usando o parâmetro params. Se não houver parâmetros customizados obrigatórios, configure params como NULL. Para preencher params, basta designar os ponteiros void na matriz a cada parâmetro customizado. Use o seguinte código C como exemplo:
int param0 = 5; char* param1 = "HELLO"; double param2 = 4.3234; void** params = (void**) malloc(sizeof(void*) * 3); params[0] = (void*) ¶m0; params[1] = (void*) param1; /*o ponteiro char não deve ser desreferenciado*/ params[2] = (void*) ¶m2; /* Chamada de função aqui....*/ free(params);
O clientes CARMA devem passar um parâmetro void*** a todas as funções do RAM definidas para retornar valores de retorno customizados. Pode-se simplesmente passar um ponteiro a uma variável void** que você define. Depois que os valores de retorno customizados tiverem sido retornados, eles poderão ser desempacotados conforme demonstra o código C a seguir. É responsabilidade do cliente liberar os retornos customizados:
/* Declarado no início */ int return0; char return1[15]; void ** returnVals = NULL; /* Chamar a função do CARMA com &returnVals para retornos customizados */ /* Desempacotar o void** (returnVals) */ return0 = *((int*) returnVals[0]); memcpy(return1, (char*) returnVals[1], 15); /*Liberar cada retorno, além da matriz*/ free(returnVals[0]); free(returnVals[1]); free(returnVals);
Ao usar um cliente CARMA, os recursos do CARMA podem obter automaticamente extensões sugeridas da propriedade de metadados especificada pelo RAM. Isso é feito para eliminar a necessidade de o usuário configurar a extensão em cada recurso do CARMA. Entretanto, em alguns casos, uma extensão pode não ser especificada pelo RAM, obrigando o cliente a fornecer uma extensão padrão. Em casos como esse, o cliente deve ser configurado para ignorar a extensão de arquivo fornecida pelo RAM e, em seu lugar, utilizar uma extensão especificado de dentro do cliente. Exemplos de como o cliente pode substituir uma extensão de arquivo especificada pelo RAM podem ser encontrados em Extensão de Arquivo Especificada pelo RAM.
O CARMA fornece aos clientes a capacidade de extrair arquivos de um SCM em um ambiente normal do host de PDSs e arquivos sequenciais.
Copia um membro de um PDS ou um SDS.
int copyFromExternal(int ramID, char instanceID[256], char memberID[256], char external[256], void** params, void*** customReturn, char error[256])
int ramID | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o membro sendo copiado |
char memberID[256] | Entrada | O ID do membro sendo copiado |
char external[256] | Entrada | O local do qual copiar. Um membro PDS ou um membro SDS. Exemplos: FEK.#CUST.EXT.STOR FEK.#CUST.EXT.PDS(MEMBER) |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Copia um membro para um PDS ou um SDS.
int copyToExternal(int ramID, char instanceID[256], char memberID[256], char target[256], void** params, void*** customReturn, char error[256])
int ramID | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o membro sendo copiado |
char memberID[256] | Entrada | O ID do membro sendo copiado |
char target[256] | Entrada | O local para o qual copiar. Um membro PDS ou um membro SDS. Exemplos: FEK.#CUST.EXT.STOR FEK.#CUST.EXT.PDS(MEMBER) |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
O CARMA espera que determinadas funções sejam executadas na ordem. Essas funções de estado e sua ordem esperada são:
Configurará o ambiente do CARMA, o log de sessão e o código de idioma de sessão
int initCarma(int traceLev, char locale[5], char error[256])
int traceLev | Entrada | O nível de rastreio para a sessão atual. Consulte Log para obter informações adicionais. |
char locale[5] | Entrada | Buffer de cinco caracteres com terminação não nula, contendo o código de idioma para o qual todas as sequências exibíveis devem ser configuradas |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Se essa função não for chamada, um código de idioma padrão igual a "EN_US" e um nível de rastreio padrão igual a 0 serão usados.
Recupera a lista de RAMs disponíveis do CARMA
int getRAMList(RAMRecord** records, int *numRecords, char error[256])
RAMRecord** records | Saída | Conterá uma matriz de estruturas de dados RAMRecord a ser usada para exibição de informações sobre os RAMs e acessá-las com outras funções |
int* numRecords | Saída | O número de estruturas de dados RAMRecord contidas na matriz records |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
A lista de RAMs que é retornada depende do código de idioma que foi passado no initializeCarma. Todos os RAMs armazenados no ambiente do CARMA que tiverem sequências de exibição para o código de idioma do cliente especificado serão retornados.
Recupera a lista de RAMs disponíveis do CARMA
int getRAMList2(RAMRecord2** records, int *numRecords, char error[256])
RAMRecord2** records | Saída | Conterá uma matriz de estruturas de dados RAMRecord2 a ser usada para exibição de informações sobre os RAMs e acessá-las com outras funções |
int* numRecords | Saída | O número de estruturas de dados RAMRecord2 contidas na matriz records |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
A lista de RAMs que é retornada depende do código de idioma que foi passado no initializeCarma. Todos os RAMs armazenados no ambiente do CARMA que tiverem sequências de exibição para o código de idioma do cliente especificado serão retornados.
Inicializa um RAM. O CARMA armazenará um ponteiro para o RAM para acesso futuro rápido.
int initRAM(int RAMid, char locale[8], char codepage[5], char error[256])
int RAMid | Entrada | Informa ao CARMA qual RAM deve ser inicializado. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char locale[8] | Entrada | Informa ao CARMA o código de idioma das sequências que devem ser retornadas ao cliente |
char codepage[5] | Entrada | Informa ao CARMA a página de códigos das sequências que devem ser retornadas ao cliente |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Diz para o RAM reconfigurar-se ao seu estado inicial
int reset(int RAMid, char error[256])
int RAMid | Entrada | Informa ao CARMA qual RAM deve ser reconfigurado. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Diz para o RAM limpar seu ambiente. O CARMA liberará o módulo do RAM.
int terminateRAM(int RAMid, char error[256])
int RAMid | Entrada | Informa ao CARMA qual RAM deve ser finalizado. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Limpará o ambiente do CARMA, incluindo os ambientes de qualquer RAM carregado
int terminateCarma(char error[256])
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Recupera a lista de instâncias disponíveis no SCM
int getInstances(int RAMid, Descriptor** RIrecords,int* numRecords, void** params, void*** customReturn, char filter[256], char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
Descriptor** RIrecords | Saída | Isso será alocado e preenchido com os IDs e os nomes das instâncias. |
int* numRecords | Saída | O número de registros que foram alocados e retornados |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de instâncias |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Nota: Certifique-se de liberar a matriz RIrecords
Recupera a lista de instâncias disponíveis no SCM e os metadados associados a essas instâncias. Essa é uma função opcional. O cliente deverá chamar essa função se desejar recuperar uma lista de instâncias e os metadados associados a todas essas instâncias. Se o RAM não suportar essa função, o cliente deverá fazer fallback para chamar getInstances.
int getInstancesWithInfo(int RAMid, DescriptorWithInfo** records, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
DescriptorWithInfo** records | Saída | Isso será alocado e preenchido com os IDs e os nomes das instâncias. Conterá também as informações de metadados para cada instância. |
int* numRecords | Saída | O número de registros que foram alocados e retornados |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de instâncias |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Recupera a lista de membros disponíveis na instância especificada
int getMembers(int RAMid, char instanceID[256], Descriptor** memberArr, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância para a qual os membros devem ser recuperados |
Descriptor** memberArr | Saída | Isso será alocado e preenchido com os IDs e os nomes das instâncias. |
int* numRecords | Saída | O número de registros que foram alocados e retornados na matriz |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de membros. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Nota: Certifique-se de liberar a matriz memberArr.
Recupera a lista de membros disponíveis na instância especificada
int getMembersWithInfo(int RAMid, char instanceID[256], MemberDescriptorWithInfo** members, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância para a qual os membros devem ser recuperados |
MemberDescriptorWithInfo** members | Saída | Isso será alocado e preenchido com os IDs e os nomes dos membros. Conterá também as informações de metadados para cada membro e se esse membro é um contêiner. |
int* numRecords | Saída | O número de registros que foram alocados e retornados na matriz |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de membros. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Configura isContainer como true se o membro for um contêiner; caso contrário, false
int isMemberContainer(int RAMid, char instanceID[256], char memberID[256], int* isContainer, void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro que pode ser um contêiner |
int* isContainer | Saída | Configure isso como 1 se o membro for um contêiner; e como 0, se não for. |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Recupera a lista de membros em um contêiner
int getContainerContents(int RAMid, char instanceID[256], char memberID[256], Descriptor** contents, int* numMembers, void** params, void*** customReturn, char filter[256], char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O contêiner para o qual os membros estão sendo recuperados |
Descriptor** contents | Saída | Isso será alocado e preenchido com os IDs e os nomes dos membros dentro do contêiner. |
int* numRecords | Saída | O número de registros de membros que foram alocados e retornados na matriz |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de membros |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Nota: Certifique-se de liberar a matriz de conteúdo.
Recupera a lista de membros disponíveis no contêiner especificado e os metadados associados a esses membros. Essa é uma função opcional. O cliente deverá chamar essa função se desejar recuperar uma lista de membros e os metadados associados a todos esses membros. Se o RAM não suportar essa função, o cliente deverá fazer fallback para chamar getContainerContents.
int getContainerContentsWithInfo(int RAMid, char instanceID[256], char memberID[256], MemberDescriptorWithInfo** members, int* numRecords, void** params, void*** customReturn, char filter[256], char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O contêiner para o qual os membros estão sendo recuperados |
MemberDescriptorWithInfo** members | Saída | Isso será alocado e preenchido com os IDs e os nomes dos membros. Conterá também as informações de metadados para cada membro e se esse membro é um contêiner. |
int* numRecords | Saída | O número de registros de membros que foram alocados e retornados na matriz |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char filter[256] | Entrada | Isso pode ser passado do cliente para filtrar conjuntos de membros |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Criar e excluir fornecem a funcionalidade para criar e excluir membros e contêineres em um ambiente do CARMA.
Cria um novo membro
int createMember(int RAMid, char instanceID[256], char memberID[256], char name[64], char parentID[256], int* lrecl, char recFM[4], void** params, void*** customReturn, char error[256]);
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o membro sendo criado |
char memberID[256] | Saída | O ID do membro que está sendo criado |
char name[64] | Entrada/Saída | O ID do membro sendo criado |
char parentID[256] | Entrada | O ID do contêiner-pai (Se nenhum pai existir, deve ser preenchido com espaço) |
int* lrecl | Saída | O número de colunas no conjunto de dados e na matriz |
char recFM[4] | Saída | Contém o formato de registro do conjunto de dados (FB, VB, ect) |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Para considerar as convenções de nomenclatura específicas do RAM, um cliente chama a operação criar solicitando um determinado nome. O RAM pode então fornecer um memberID, lrecl, recFM e um nome exibível apropriado exclusivos de volta ao cliente.
Se o cliente solicitar o nome "bob", por exemplo, o RAM poderá retornar um memberID igual a "BOB", bem como um nome exibível igual a "BOB". Se o membro "bob" já existir, ele poderá retornar "BOB2", ou então retornar um erro informando que não é possível criar o membro solicitado.
parentID é o memberID para o pai do membro que está sendo criado. Se o membro sendo criado não tiver um pai (está diretamente na instância de repositório), parentID deverá ser deixado em branco (tudo com espaços).
Um RAM não precisa criar um membro quando createMember é chamado, mas pode apenas fornecer o memberID, lrecl, recFM e o nome exibível adequados ao cliente. É responsabilidade do cliente fazer uma chamada para putMember com o novo memberID a fim de criar um membro concreto. Os RAMs devem suportar a inclusão de um membro sem registros (mesmo que tenham de criar um único registro em branco para o membro).
Cria um novo contêiner
int createContainer(int RAMid, char instanceID[256], char memberID[256], char name[64], char parentID[256], void** params, void*** customReturn, char error[256]);
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o contêiner sendo criado |
char memberID[256] | Saída | O ID do membro que está sendo criado |
char name[64] | Entrada/Saída | O ID do contêiner sendo criado |
char parentID[256] | Entrada | O ID do contêiner-pai (Se nenhum pai existir, deve ser preenchido com espaço) |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Para considerar as convenções de nomenclatura específicas do RAM, um cliente chama a operação criar solicitando um determinado nome. O RAM pode então fornecer um memberID, lrecl, recFM exclusivos e um nome exibível apropriado de volta ao cliente.
Se o cliente solicitar o nome "bob", por exemplo, o RAM poderá retornar um memberID igual a "BOB", bem como um nome exibível igual a "BOB". Se o contêiner "bob" já existir, ele poderá retornar "BOB2", ou então retornar um erro informando que não é possível criar o contêiner solicitado.
parentID é o memberID para o pai do contêiner que está sendo criado. Se o contêiner sendo criado não tiver um pai (está diretamente na instância de repositório), parentID deverá ser deixado em branco (tudo com espaços).
Ao contrário da função createMember, quando createContainer é chamado, o contêiner deve sempre ser criado imediatamente pelo RAM, a menos que um erro ocorra.
Exclui um membro ou contêiner
int delete(int RAMid, char instanceID[256], char memberID[256], int force, void** params, void*** customReturn, char error[256]);
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o membro ou o contêiner sendo excluído |
char memberID[256] | Entrada | O ID do membro que está sendo excluído |
int force | Entrada | Usado para forçar uma exclusão. Um valor igual a 1 forçará uma exclusão |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
O parâmetro force pode ser configurado como 1 para ordenar a um RAM que exclua um membro que ele normalmente não excluiria, como um contêiner não vazio. Se um RAM puder excluir um item, mas precisar de um parâmetro force para fazê-lo, ele poderá enviar um determinado código de retorno, com um erro apropriado, para informar ao cliente. O cliente pode então oferecer a opção de excluir com o parâmetro force.
Como opção, o cliente pode também permitir que o usuário configure o parâmetro force antes de chamar a exclusão.
A função de exclusão pode ser usada para excluir membros e contêineres; entretanto, não deve ser usada para excluir uma Instância do RAM.
Recupera o conteúdo do membro
int extractMember(int RAMid, char instanceID[256], char memberID[256], char*** contents, int* lrecl, int* numRecords, char recFM[4], int* moreData, int* nextRec, void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o membro |
char memberID[256] | Entrada | O ID do membro que está sendo extraído |
char*** contents | Saída | Será alocado como matriz bidimensional para manter o conteúdo do membro |
int* lrecl | Saída | O número de colunas no conjunto de dados e na matriz |
int* numRecords | Saída | O número de registros no conjunto de dados ou o número de linhas na matriz |
char recFM[4] | Saída | Conterá o formato de registro do conjunto de dados (FB, VB, etc.) |
int* moreData | Saída | Configure como 1 o valor da variável para o qual isso aponta, se a extração tiver de ser chamada novamente (por ainda haver mais dados a serem extraídos). Caso contrário, designe como 0 o valor para o qual ela aponta. |
int* nextRec | Entrada/Saída |
Entrada: O registro do membro no qual o RAM deve iniciar extração Saída: O primeiro registro no conjunto de dados que não foi extraído se *moreData estiver configurado como 1; caso contrário, indefinido |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
O buffer de conteúdo é uma matriz de caracteres bidimensional que será preenchida pelo RAM e retornada ao cliente. Para a primeira chamada extractMember, nextRec deverá ser 0. O RAM pode optar por retornar os dados em chunks de registros. A extração deve ser chamada até que moreData seja 0. Se moreData for 1, extractMember precisará ser chamado novamente, e a extração do membro será iniciada com o registro indexado pelo valor de nextRec retornado na chamada anterior. O RAM precisará que o cliente passe esse valor de nextRec de volta para a chamada seguinte.
Consulte Desenvolvendo um RAM para obter um exemplo da operação de extractMember do ponto de vista do RAM.
Nota: Certifique-se de liberar contents adequadamente. Ele foi alocado como um grande chunk de dados contíguos, por isso deve ser liberado da seguinte maneira (o exemplo é em C):
for(i = 0; i < numRecords; i++) free(contents[i]); free(contents);
Atualiza o conteúdo de um membro ou cria um novo membro se o memberID especificado não existir na instância
int putMember(int RAMid, char instanceID[256], char memberID[256], char** contents, int lrecl, int* numRecords, char recFM[4], int moreData, int nextRec, int eof, void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o membro |
char memberID[256] | Entrada | O ID do membro que está sendo atualizado/criado |
char** contents | Entrada | Mantém o novo conteúdo do membro |
int lrecl | Entrada | O número de colunas no conjunto de dados e na matriz |
int* numRecords | Entrada/Saída | O número de registros no conjunto de dados ou o número de linhas na matriz |
char recFM[4] | Entrada | Contém o formato de registro do conjunto de dados (FB, VB etc.) |
int moreData | Entrada | Será 1 se o cliente tiver mais chunks de dados para enviar; caso contrário, 0 |
int nextRec | Entrada | O registro no conjunto de dados para o qual o registro 0 da matriz de conteúdo é mapeado |
int eof | Entrada | Se 1, indica que a última linha da matriz deverá marcar a última linha no conjunto de dados; caso contrário, 0. |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
O cliente pode escolher um tamanho de chunk para a função ou tentar passar todo o conteúdo do arquivo de uma vez. O cliente pode também optar por dar voltas dentro de um arquivo. Por exemplo, os registros de 0 a 15 podem ser passados primeiro, de 40 a 50 depois e, em seguida, 16 a 30. Entretanto, nem todos os RAMs podem manipular chunks de dados não sequenciais dessa forma adequadamente.
Para envio de dados em chunks, moreData deve ser 1 em cada chamada até a chamada final, durante a qual deve ser 0. nextRec deve sempre ser configurado como o primeiro registro a ser atualizado no membro. Lembre-se de que isso usa um índice baseado em 0. eof é usado para especificar que o registro do membro em nextRec + numRecords deve ser o último no membro atualizado. Por exemplo, se essa soma for 15 e houver atualmente 30 registros no membro, os registros de 16 a 29 serão excluídos pelo RAM depois que ele atualizar até o registro 15.
Consulte a origem do cliente de amostra (CRACLISA na biblioteca de amostra) para obter mais ajuda.
Nota: O buffer de conteúdo deve ser alocado antes da chamada de maneira semelhante à seguinte (o exemplo é em C):
contents = (char**) malloc(sizeof(char*) * (numRecords)); *contents = (char*) malloc(sizeof(char) * (lrecl) * (numRecords)); for(i = 0; i < numRecords; i++) (contents)[i] = ((*contents) + (i * (lrecl)));
e deve ser liberado após a chamada de maneira semelhante à seguinte (o exemplo é em C):
free(contents[0]) free(contents);
Recupera o conteúdo do membro.
int putBinMember(int RAMid, char instanceID [256], char memberID [256], char** contents, int* length, int* moreData, int start, void** params, void*** customReturn, char error [256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o membro sendo extraído. |
char memberID[256] | Entrada | O ID do membro que está sendo extraído. |
char** contents | Saída | Ponteiro para o conteúdo do membro |
int* length | Saída | O comprimento do conteúdo do membro. |
int* moreData | Saída | Se a extração precisar ser chamada novamente porque há mais dados, configure como 1 o valor da variável para o qual isso aponta, ou então designe como 0 o valor para o qual ela aponta. |
int start | Entrada | O local de byte do arquivo do qual iniciar a extração. |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Atualiza o conteúdo de um membro ou cria um novo membro se o memberID especificado não existir na instância.
int putBinMember(int RAMid, char instanceID [256], char memberID [256], char* contents, int length, int moreData, int start, void** params, void*** customReturn, char error [256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância que contém o membro sendo atualizado/criado. |
char memberID[256] | Entrada | O ID do membro que está sendo atualizado/criado. |
char* contents | Entrada | Mantém o novo conteúdo dos membros. |
int length | Entrada | Ponteiro para o comprimento dos dados a serem gravados. |
int moreData | Entrada | Será 1 se o cliente tiver mais chunks de dados para enviar; caso contrário, 0. |
int start | Entrada | O local de byte do arquivo para iniciar a colocação de dados. |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Recupera todos os metadados para o membro determinado
int getAllMemberInfo(int RAMid, char instanceID[256], char memberID[256], KeyValPair** metadata, int* num, void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O ID do membro para o qual metadados estão sendo retornados. O ID poderá ficar vazio se as informações do membro forem recuperadas para a instância e não para um membro específico. |
KeyValPair** metadata | Saída | Isso será alocado e preenchido com chaves e valores dos metadados. |
int* num | Saída | O número de estruturas de metadados KeyValPair alocado e retornado na matriz |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Nota: Certifique-se de liberar a matriz de metadados.
Recupera os dados dos campos para o determinado RAM. Os campos fornecem sugestões para metadados que devem ser exibidos ao usuário.
int getFieldsData(int RAMid, Field** fields, int * numFields, char error[256])
int RAMid | Entrada | Informa ao CARMA para qual RAM reunir dados. Esse ID foi obtido após a execução de getRAMList. |
Field** fields | Saída | Isso será alocado e preenchido com ID, chave de metadados, nome, valor padrão e descrição de cada campo. |
int * numFields | Saída | O número de estruturas de Campo alocadas e preenchidas na matriz. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Recupera os dados dos campos para o determinado RAM. Os campos fornecem sugestões para metadados que devem ser exibidos ao usuário.
int getFieldsData2(int RAMid, Field2** fields, int * numFields, char error[256])
int RAMid | Entrada | Informa ao CARMA para qual RAM reunir dados. Esse ID foi obtido após a execução de getRAMList2. |
Field2** fields | Saída | Isso será alocado e preenchido com ID, chave de metadados, nome, valor padrão e descrição de cada campo. |
int * numFields | Saída | O número de estruturas de Campo alocadas e preenchidas na matriz. |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Recupera uma parte específica de metadados para o membro determinado
int getMemberInfo(int RAMid, char instanceID[256], char memberID[256], char key[64], char value[256], void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro para o qual metadados estão sendo recuperados |
char key[64] | Entrada | A chave do valor de metadado a ser recuperado |
char value[256] | Saída | O valor que está sendo recuperado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Atualiza uma parte específica de metadados para o membro determinado
int updateMemberInfo(int RAMid, char instanceID[256], char memberID[256], char key[64], char value[256], void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro para o qual metadados estão sendo configurados |
char key[64] | Entrada | A chave do valor de metadado a ser configurada |
char value[256] | Entrada | O valor que está sendo configurado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Bloqueia o membro
int lock(int RAMid, char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro a ser bloqueado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Desbloqueia o membro
int unlock(int RAMid, char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro a ser desbloqueado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Efetue o registro de entrada do membro. Isso apenas configura um sinalizador. Uma chamada putMember é esperada imediatamente após essa chamada.
int checkin(int RAMid, char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro cujo registro de entrada é efetuado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Efetue o registro de saída do membro. Isso apenas configura um sinalizador. Uma chamada extractMember é esperada imediatamente após essa chamada.
int checkout(int RAMid, char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro cujo registro de saída é efetuado |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Instrui o RAM especificado a retornar a ação identificada no actionID usando os parâmetros fornecidos e os valores de retorno em customReturn (quando aplicável).
int performAction(int RAMid, int actionID, char instanceID[256], char memberID[256], void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA o RAM no qual trabalhar. Esse ID foi obtido após a execução de getRAMList ou getRAMList2 |
int actionID | Entrada | A ação customizada que está sendo solicitada, conforme definido no CRADEF VSAM. |
char instanceID[256] | Entrada | A instância na qual a ação está sendo executada. O ID poderá ficar em branco caso se espere que a ação seja executada no próprio RAM, em vez de em uma instância ou membro específico. |
char memberID[256] | Entrada | O membro no qual a ação está sendo executada. O ID poderá ficar em branco caso se espere que a ação seja executada em uma instância ou no próprio RAM, em vez de em um membro específico. |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Recupera os dados do CAF para o RAM solicitado
int getCAFData(int RAMid, Action** actions, int* numActions, int** disabledActions, int* numDisabled, Parameter** params, int* numParams, returnValue** returnVals, int* numReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA para qual RAM os dados do CAF devem ser extraídos. Esse ID foi obtido após a execução de getRAMList. |
Action** actions | Saída | Isso será alocado e preenchido com as ações customizadas para o determinado RAM. |
int* numActions | Saída | O número de ações sendo retornadas |
int** disabledActions | Saída | Isso será alocado e preenchido com as ações desativadas para o determinado RAM. |
int* numDisabled | Saída | O número de ações desativadas sendo retornadas |
Parameter** params | Saída | Isso será alocado e preenchido com os parâmetros customizados para o determinado RAM. |
int* numParams | Saída | O número de parâmetros sendo retornados |
returnValue** returnVals | Saída | Isso será alocado e preenchido com os valores de retorno customizados para o determinado RAM. |
int* numReturn | Saída | O número de valores de retorno sendo retornados |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Consulte o Customizando uma API do RAM Usando o CAF para obter mais informações sobre os tipos de dados que podem ser retornados. Os dados retornados devem ser armazenados durante o restante da sessão para que possam ser verificados antes de qualquer chamada de função para o respectivo RAM.
Recupera os dados do CAF para o RAM solicitado
int getCAFData2(int RAMid, Action2** actions, int* numActions, int** disabledActions, int* numDisabled, Parameter2** params, int* numParams, returnValue2** returnVals, int* numReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA para qual RAM os dados do CAF devem ser extraídos. Esse ID foi obtido após a execução de getRAMList2. |
Action2** actions | Saída | Isso será alocado e preenchido com as ações customizadas para o determinado RAM. |
int* numActions | Saída | O número de ações sendo retornadas |
int** disabledActions | Saída | Isso será alocado e preenchido com as ações desativadas para o determinado RAM. |
int* numDisabled | Saída | O número de ações desativadas sendo retornadas |
Parameter2** params | Saída | Isso será alocado e preenchido com os parâmetros customizados para o determinado RAM. |
int* numParams | Saída | O número de parâmetros sendo retornados |
returnValue2** returnVals | Saída | Isso será alocado e preenchido com os valores de retorno customizados para o determinado RAM. |
int* numReturn | Saída | O número de valores de retorno sendo retornados |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
Consulte o Customizando uma API do RAM Usando o CAF para obter mais informações sobre os tipos de dados que podem ser retornados. Os dados retornados devem ser armazenados durante o restante da sessão para que possam ser verificados antes de qualquer chamada de função para o respectivo RAM.
Fornece uma lista de versões disponíveis para um determinado membro
int getVersionList(char instanceID[256], char memberID[256], VersionIdent** versions, int* num, void** params, void*** customReturn, char error[256])
int RAMid | Entrada | Informa ao CARMA para qual RAM os dados do CAF devem ser extraídos. Esse ID foi obtido após a execução de getRAMList ou getRAMList2. |
char instanceID[256] | Entrada | A instância na qual o membro está |
char memberID[256] | Entrada | O membro para o qual obter uma lista de versões |
VersionIdent** versions | Saída | Uma lista de todas as versões do membro disponíveis. Deve ser uma lista ordenada, com a versão ‘mais recente' primeiro e a versão mais antiga por último. |
int* num | Saída | O número de versões |
void** params | Entrada | Ponteiro para uma matriz de parâmetros customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
void*** customReturn | Saída | Usado para referenciar uma matriz de valores de retorno customizados (consulte Manipulando Parâmetros e Valores de Retorno Customizados) |
char error[256] | Saída | Se um erro ocorrer, deverá ser preenchido com uma descrição do erro. |
VersionIdent será identificado pela seguinte estrutura:
typedef struct { char memberID[256]; /*Um memberID com versão, como baseMemberID_VerNum*/ char versionKey[64]; /* Uma maneira de se referir à versão, como "1.2.3"...deve ser igual ao valor para a chave de metadados carma.version*/ char comments[256]; /* Os comentários fornecidos pelo RAM sobre a versão, podem ser registro de data/hora, mudanças, etc.. */ } VersionIdent;
A lista de versões será uma lista completa de versões ordenadas, mas o Desenvolvedor do RAM pode optar por usar um ID ‘com versão' para a versão atual ou usar o ID inalterado. Como exemplo, a versão atual de um membro pode ser acessível por meio de "location(Member)" ou "location(Member)_1.4", em que o arquivo está na versão 1.4. O desenvolvedor do RAM pode portanto optar por retornar "location(Member)_1.4" ou "location(Member)" como a versão mais recente na lista.
Ao retornar uma lista de membros por meio das funções de navegação, como getMembers, os RAMs NÃO DEVEM incluir a versão no memberID. Alterar o memberID para um membro impede que os clientes CARMA rastreiem adequadamente esse membro.
Para suportar versão, os Desenvolvedores do RAM devem manipular as chamadas do CARMA quando apresentadas com um ID ‘com versão' para o memberID.
Os clientes devem suportar o código de retorno 130, que significa "O membro não suporta versão"
Os clientes podem suportar uma variedade de chamadas com relação a membros com versão, como as funções de transferência de arquivo e as funções de metadados.
Código de Retorno | Descrição |
---|---|
20 | Erro interno |
22 | Nenhuma RAM definida para este código do idioma |
24 | CRADEF não pôde ser aberto para leitura |
25 | CRASTRS não pôde ser aberto para leitura |
26 | Nenhum registro localizado em CRADEF |
28 | Erro de leitura do CRADEF |
30 | (marcador) |
32 | Foi encontrado registro inválido do CRADEF |
34 | RAM solicitado não localizado |
36 | Não foi possível carregar o módulo do RAM |
38 | Não foi possível carregar o ponteiro para a função do RAM |
40 | O RAM solicitado nome do RAM não foi carregado |
42 | Foi encontrado registro inválido do CRASTRS |
44 | O CARMA não foi inicializado |
46 | Falha ao tentar carregar a lista RAM |
48 | Sem memória |
50 | O registro no CRADEF não tem equivalente no CRASTRS para esse código de idioma |
52 | A ação faz referência a parâmetro desconhecido |
54 | A ação faz referência a tipo de retorno desconhecido |
56 | Erro de leitura do CRASTRS |
58 | Não foi possível localizar nem o código do idioma especificado nem o padrão (EN_US, página de códigos 00037) no CRASTRS |
60 | CRAMSG não localizado |
62 | Erro de leitura do CRAMSG |
64 | Erro do CRADEF: A ação 16 não pode ter parâmetros e/ou retornos customizados |
66 | Tipo inválido especificado no registro VSAM |
68 | Valor padrão inválido no registro VSAM |
101 | Não foi possível alocar memória |
102 | Funções da biblioteca TSO/ISPF não disponíveis |
103 | Identificador de membro inválido |
104 | Não é possível alocar (sem espaço) |
105 | Membro não localizado |
106 | Instância não localizada |
107 | Função não suportada |
108 | O membro não é um contêiner |
109 | Valor de parâmetro inválido |
110 | O membro não pode ser atualizado |
111 | O membro não pode ser criado |
112 | Não Autorizado |
113 | Não foi possível inicializar |
114 | Não foi possível finalizar |
115 | Recurso fora de sincronização |
116 | Arquivo bloqueado |
117 | Próximo registro especificado fora do intervalo |
118 | Formato de registro não suportado |
119 | LRECL inválido |
120 | Chave de metadados inválida |
121 | Não é possível atualizar o valor da propriedade |
122 | Valor de metadados inválido |
123 | O valor da propriedade é de leitura |
124 | O membro solicitado está vazio |
125 | Instância vazia |
126 | Nenhum membro localizado |
127 | Erro de reconfiguração |
128 | Erro de exclusão |
129 | Membro/Versão é somente leitura |
130 | O membro não suporta versão |
197 | (mensagem de erro ISPF/LMF encapsulada) |
198 | Impossível acessar o arquivo de log |
199 | Erro desconhecido de RAM |
222 | Erro ao recuperar lista de parâmetros da Estrutura da Ação Customizada |
223 | Está faltando um parâmetro esperado da Estrutura de Ação Customizada |
224 | Tipo de dados desconhecido especificado para o parâmetro da Estrutura de Ação Customizada |
225 | Erro ao recuperar valores de retorno da Estrutura da Ação Customizada |
ID da Ação | Nome da Ação |
---|---|
0 | initRam |
1 | terminateRam |
1 | getMembers |
3 | extractMember |
4 | putMember |
5 | getAllMemberInfo |
6 | getMemberInfo |
7 | updateMemberInfo |
8 | isMemberContainer |
9 | getContainerContents |
10 | lock |
11 | unlock |
12 | checkIn |
13 | checkOut |
14 | getInstances |
15 | reset |
16 | performAction |
17 | createMember |
18 | createContainer |
19 | delete |
20 | copyToExternal |
21 | copyFromExternal |
22 | putBinMember |
23 | extractBinMember |
24 | getVersionList |
25 | getMembersWithInfo * |
26 | getContainerContentsWithInfo * |
27 | getInstancesWithInfo * |
80 | initCarma |
81 | terminateCarma |
82 | getRAMList |
83 | getCAFData |
Este apêndice funciona como um recurso para os RAMs de amostra que são enviados com o Common Access Repository Manager (CARMA). Os RAMs de amostra são fornecidos com o propósito de testar a configuração do ambiente CARMA e como exemplos para que você desenvolva seus próprios RAMs. NÃO utilize os RAMs de amostra fornecidos em um ambiente de produção.
O RAM Partitioned Data Set (PDS) permite que você acesse um PDS associado a usuários do TSO alavancando os serviços do ISPF. Nesse caso, os serviços do TSO/ISPF são o SCM e o repositório é o PDS do usuário.
No RAM PDS, o CARMA exibe uma lista de todos os conjuntos de dados PDS que estão disponíveis a você em uma conexão específica. Cada PDS pode então ser expandido para exibir uma coleção de Conjuntos de Dados Sequenciais (SDS), também chamados membros que compõem cada PDS.
As seguintes ações estão disponíveis atualmente apenas para arquivos com um formato de registro de "Bloco Fixo".
As seguintes ações do CARMA não são suportadas pelo PDS RAM, pois não possui recursos de controle de versão:
O RAM de amostra do Software Configuration Library Manager (SCLM) é outra demonstração da capacidade do CARMA de fazer interface com os Source Code Managers (SCMs). O propósito deste apêndice é dar ao desenvolvedor do RAM um entendimento da implementação do RAM SCLM do CARMA. O RAM SCLM faz interface com um IBM Software Configuration and Library Manager (SCLM).
O IBM SCLM fornece uma API semelhante ao ISPF que fornece o gerenciador de diálogo. Além disso, o SCLM faz interface com os serviços de gerenciamento de biblioteca do ISPF para a maioria de suas funções. O ISPF/SCLM cria e acessa variáveis, listas e relatórios como resultado das chamadas de API que ele faz. Para obter uma descrição completa de todos os serviços de programação do ISPF/SCLM, consulte o Software Configuration Library Manager Reference, z/OS Versão 1 Liberação 7.0, e também o manual de serviços do ISPF para obter informações detalhadas sobre serviços de gerenciamento de biblioteca do ISPF. O CARMA utiliza os serviços de gerenciamento de biblioteca do ISPF e os serviços do SCLM no RAM de amostra do SCLM.
No RAM SCLM, o CARMA exibe um projeto do SCLM selecionado que está disponível a você em uma conexão específica. Cada projeto do SCLM pode então ser expandido para exibir os grupos e os tipos associados ao projeto.
O RAM de amostra do SCLM usa as principais funções do ISPF e do SCLM na Interface com o Usuário do CARMA. Essa funcionalidade permite que os usuários enviem solicitações ao RAM SCLM no host do z/OS e, em seguida, exibam os resultados em suas estações de trabalho. Segue uma lista de funções do SCLM que podem ser chamadas a partir de uma seleção do membro na UI do CARMA.
Nome da Função | Descrição |
---|---|
LOCK | Essa é uma função independente que permite a um usuário bloquear um membro ou incluir uma chave de acesso para limitar ou restringir o acesso a ela por outros usuários. Essa função pode ser ativada clicando com o botão direito do mouse em um membro do SCLM na UI do CARMA e selecionando Bloquear no menu de contexto. |
UNLOCK | Esta função desbloqueará um membro que foi bloqueado removendo a chave de acesso. Ela pode ser acessada clicando com o botão direito do mouse no membro bloqueado na UI do CARMA e selecionando Desbloquear no menu de contexto. |
DELETE | Essa função excluirá todos os rastreios de um membro do SCLM, incluindo todo texto e metadados, de um projeto do SCLM. Essa função pode ser acessada clicando com o botão direito do mouse em um membro do SCLM na UI do CARMA e selecionando Excluir no menu de contexto. |
As funções a seguir são ações customizadas que são específicas do conteúdo do RAM SCLM. Elas podem ser acessadas clicando com o botão direito do mouse em um membro do SCLM na UI do CARMA e selecionando Customizado no menu de contexto.
Nome do Serviço | Descrição |
---|---|
MIGRATE | O serviço MIGRATE cria ou atualiza as informações de conta do SCLM para membros em uma biblioteca de desenvolvimento. A correspondência de padrões não é fornecida nesse momento. |
BUILD | O serviço BUILD compila, vincula e integra componentes de software de acordo com a definição de arquitetura do projeto. Antes que um membro seja construído entretanto, as informações de dependência do membro devem existir no banco de dados do projeto. Por essa razão, o serviço STORE ou SAVE para um membro deve ser concluído com êxito para que o serviço BUILD possa ser executado. |
PROMOTE | O serviço PROMOTE move dados, ou promove dados, por meio do banco de dados do projeto de acordo com a definição e a arquitetura do projeto. Para que o SCLM possa promover um membro, ele deve ter uma chave de acesso em branco, além de ter concluído com êxito o serviço BUILD. Se um membro tiver uma chave de acesso, você deverá chamar o serviço UNLOCK para reconfigurar a chave a fim de que seja possível promover o membro. |
DELETE | O serviço DELETE exclui os componentes do banco de dados. Você pode excluir um membro inteiro, seus registros de conta associados e o mapa de construção, apenas os registros de conta e o mapa de construção ou simplesmente o mapa de construção do membro. |
EDIT | O serviço EDIT não é como a edição do SCLM. Em vez disso, é usado para anunciar a intenção de uma edição. O usuário será solicitado a informar o grupo de desenvolvimento para o qual mover o membro. Uma atualização é necessária para que o usuário possa selecionar o membro no nível de desenvolvimento, clicando duas vezes no membro. Nesse ponto, o código de origem aparecerá no painel de edição da UI. |
Seguem os serviços da API do SCLM que o RAM SCLM usa para fornecer funcionalidade.
Nome do Serviço | Descrição |
---|---|
SCLMINFO | O serviço SCLMINFO é usado pela função getmembers do CARMA para recuperar todos os grupos e tipos do SCLM armazenados nas variáveis do ISPF para recuperação posterior de getContainer. |
SAVE | O serviço SAVE bloqueia e analisa um membro e depois prossegue para armazenar as informações estatísticas, de dependência e históricas desse membro, tudo em uma só chamada. O serviço SAVE chamado na função putMember do CARMA chama os serviços do SCLM LOCK, PARSE e STORE. |
Os serviços a seguir do SCLM mantêm a integridade de sessão nas funções existentes do CARMA.
Nome do Serviço | Descrição |
---|---|
INIT | O serviço INIT inicializa um ID do SCLM. Durante esse processo, ele também inicializa a definição de projeto especificada. |
START | O serviço START inicializa uma sessão de serviços do SCLM. Ele gera um ID do aplicativo que identifica a sessão de serviços. |
END | O serviço END para uma sessão de serviço do SCLM e libera um ID de aplicativo gerado pelo serviço START. Cada chamada de serviço START precisa de uma chamada de serviço END correspondente. Esse serviço também chama o serviço FREE para liberar qualquer ID do SCLM associado ao determinado ID do aplicativo que não foi liberado explicitamente. |
FREE | O serviço FREE libera um ID do SCLM gerado pelo serviço INIT. Cada chamada de serviço INIT precisa de uma chamada de serviço FREE correspondente. Depois de liberar o ID do SCLM, o SCLM fecha todos os conjuntos de dados do projeto e libera a definição de projeto especificada no serviço INIT. |
O SCLM RAM não suporta as ações a seguir. A tentativa de execução de qualquer uma destas ações resultará em um diálogo de erro.
Para obter acesso exclusivo a um arquivo de origem para edição, utilize a ação Lock. Outros usuários ainda poderão acessar o arquivo de origem extraindo-o do repositório, mas eles não poderão efetuar registro de entrada de suas atualizações para este arquivo até desbloqueá-lo.
Para permitir que outro usuário edite um arquivo de origem, utilize a ação Unlock.
O RAM COBOL é uma implementação do RAM PDS escrito em COBOL. É constituído de uma DLL que resulta do link da origem COBOL e C compilada. O RAM COBOL fornece funcionalidade para navegar em ativos PDS da mesma maneira que o RAM de amostra PDS. Alguma funcionalidade presente no RAM PDS não é implementada, mas programas esqueleto são fornecidos para implementação de funcionalidade adicional.
No RAM COBOL, o CARMA exibe uma lista de todas as instâncias PDS disponíveis com o qualificador de alto nível do usuário no host do CARMA. Cada instância pode assim ser expandida para exibir a lista de membros que compõem cada instância.
As funções a seguir já estão configuradas no RAM COBOL de amostra. Dependendo do que o RAM COBOL estará suportando, funções adicionais podem precisar ser implementadas.
Extrai um membro da mesma maneira que um RAM PDS. A função é codificada de modo que a extração de qualquer membro associado a uma instância do RAM COBOL retornará os registros de um conjunto de dados referenciado pela DD CBLIN. Essa DD deve ser incluída no CLIST de inicialização do CARMA para que extractMember funcione.
Armazena um membro PDS à instância PDS especificada.
Fornece uma lista de instâncias PDS.
Retorna a lista de membros associados a uma instância PDS.
Configura variáveis globais e demonstra a função de criação de log de COBOL para C.
Contém código de amostra para executar uma ação customizada. A amostra para performAction aceita parâmetros customizados e, em seguida, fornece-os como retornos customizados em ordem inversa. As informações de configuração do CAF para usar a ação customizada podem ser encontradas na documentação do programa para performAction.
Para obter informações mais detalhadas, consulte Desenvolvimento do RAM Usando COBOL
O RAM Esqueleto é o mais básico dentre todas as amostras. Ele fornece uma estrutura simples que pode ser usada para desenvolver um RAM que atenderá suas necessidades. Esse RAM deve ser usado como ponto de início para desenvolver seu próprio RAM customizado.
© Copyright IBM Corporation - 2010
Direitos Restritos para Usuários do Governo dos Estados Unidos - Uso, duplicação e divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corp.
Para pedidos de licenças com relação a informações sobre DBCS (Conjunto de Caracteres de Byte Duplo), entre em contato com o Departamento de Propriedade Intelectual da IBM em seu país ou envie pedidos de licença, por escrito, para:
O parágrafo a seguir não se aplica ao Reino Unido ou a nenhum país em que tais disposições estejam inconsistentes com a legislação local: A INTERNATIONAL BUSINESS MACHINES CORPORATION FORNECE ESTA PUBLICAÇÃO "NO ESTADO EM QUE SE ENCONTRA", SEM GARANTIA DE NENHUM TIPO, SEJA EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO, AS GARANTIAS IMPLÍCITAS DE NÃO-INFRAÇÃO, COMERCIALIZAÇÃO OU ADEQUAÇÃO A UM DETERMINADO PROPÓSITO. Alguns países não permitem a exclusão de garantias expressas ou implícitas em determinadas transações; portanto, esta disposição pode não se aplicar ao Cliente.
Essas informações podem conter imprecisões técnicas ou erros tipográficos. São feitas alterações periódicas nas informações aqui contidas; tais alterações serão incorporadas em futuras edições desta publicação. A IBM pode, a qualquer momento, aperfeiçoar e/ou alterar os produtos e/ou programas descritos nesta publicação a qualquer momento sem aviso prévio.
Referências nestas informações a Web sites que não sejam da IBM são fornecidas apenas por conveniência e não representam de forma alguma um endosso a estes Web sites. Os materiais contidos nesses Web sites não fazem parte dos materiais deste produto IBM e a utilização desses Web sites é de inteira responsabilidade do Cliente.
A IBM pode utilizar ou distribuir as informações fornecidas da forma que julgar apropriada sem incorrer em qualquer obrigação para com o Cliente.
Licenciados deste programa que desejam obter informações sobre este assunto com objetivo de permitir: (i) a troca de informações entre programas criados independentemente e outros programas (incluindo este) e (ii) a utilização mútua das informações trocadas, devem entrar em contato com:
Tais informações podem estar disponíveis, sujeitas a termos e condições apropriados, incluindo em alguns casos o pagamento de uma taxa.
O programa licenciado descrito nesta publicação e todo o material licenciado disponível são fornecidos pela IBM sob os termos do Contrato com o Cliente IBM, do Contrato de Licença de Programa Internacional IBM ou de qualquer outro contrato equivalente.
Quaisquer dados de desempenho contidos aqui foram determinados em ambientes controlados. Portanto, os resultados obtidos em outros ambientes operacionais poderão variar significativamente. Algumas medidas podem ter sido tomadas em sistemas em nível de desenvolvimento e não há garantia de que estas medidas serão as mesmas em sistemas disponíveis em geral. Além disso, algumas medidas podem ter sido estimadas por extrapolação. Os resultados reais podem ser diferentes. Os usuários deste documento devem verificar os dados aplicáveis para o ambiente específico.
As informações sobre produtos não-IBM foram obtidas junto aos fornecedores dos respectivos produtos, de seus anúncios publicados ou de outras fontes disponíveis publicamente. A IBM não testou estes produtos e não pode confirmar a precisão de seu desempenho, compatibilidade nem qualquer outra reivindicação relacionada a produtos não IBM. Dúvidas sobre os recursos de produtos não IBM devem ser encaminhadas diretamente a seus fornecedores.
Todas as declarações relacionadas aos objetivos e intenções futuras da IBM estão sujeitas a alterações ou cancelamento sem aviso prévio e representam apenas metas e objetivos.
Estas informações contêm exemplos de dados e relatórios usados nas operações diárias de negócios. Para ilustrá-los da forma mais completa possível, os exemplos podem incluir nomes de indivíduos, empresas, marcas e produtos. Todos estes nomes são fictícios e qualquer semelhança com nomes e endereços utilizados por uma empresa real é mera coincidência.
Essas informações contêm programas de exemplos aplicativos na linguagem fonte, ilustrando as técnicas de programação em diversas plataformas operacionais. O Cliente pode copiar, modificar e distribuir estes programas de exemplo sem a necessidade de pagar à IBM, com objetivos de desenvolvimento, utilização, marketing ou distribuição de programas aplicativos em conformidade com a interface de programação de aplicativo para a plataforma operacional para a qual os programas de exemplo são criados. Esses exemplos não foram completamente testados em todas as condições. Portanto, a IBM não pode garantir ou implicar confiabilidade, manutenção, ou função destes programas. Os programas de amostra são fornecidos "NO ESTADO EM QUE SE ENCONTRAM", sem garantia de qualquer tipo. A IBM não será responsabilizada por qualquer dano decorrente do uso dos programas de amostra.
IBM, o logotipo IBM e ibm.com são marcas ou marcas registradas da International Business Machines Corp., registradas em várias jurisdições no mundo todo. Outros nomes de produtos e serviços podem ser marcas registradas da IBM ou de outras empresas. Uma lista atual das marcas registradas da IBM está disponível na Web em www.ibm.com/legal/copytrade.shtml.
Rational é uma marca registrada da International Business Machines Corporation e da Rational Software Corporation nos Estados Unidos e/ou em outros países.
Intel e Pentium são marcas registradas da Intel Corporation nos Estados Unidos e/ou em outros países.
Microsoft, Windows e o logotipo Windows são marcas ou marcas registradas da Microsoft Corporation nos Estados Unidos e/ou em outros países.
Java e todas as marcas e logotipos baseados em Java são marcas ou marcas registradas da Sun Microsystems, Inc. nos Estados Unidos e em outros países.
UNIX é uma marca registrada da The Open Group nos Estados Unidos e em outros países.