Você está na página 1de 166

WEBSPEED APPLICATION DEVELOPMENT

ndice

ndice
Prefcio

OBJETIVO................................................................................................................................... V
TIPOGRAFIA................................................................................................................................ V
OBSERVAES EM SINTAXES ..................................................................................................... VI
REFERNCIAS BIBLIOGRFICAS ................................................................................................ VIII
1. Introduo
2. Ferramentas do WebSpeed

9
10

2.1. APPBUILDER ..................................................................................................................... 10


2.1.1. Desenvolvimento Grfico e Procedural .......................................................... 10
2.1.2. SmartDataObjects ........................................................................................... 10
2.1.3. Templates e Wizards ...................................................................................... 10
2.1.4. Editores de Texto ............................................................................................ 11
2.2. EXECUTANDO O W EBSPEED NO APPBUILDER .................................................................. 11
2.2.1. Configurao do WebSpeed ........................................................................... 11
2.2.2. Identificando o Browser Padro e o Broker do WebSpeed ............................ 12
2.2.3. Setando o Modo de Desenvolvimento ............................................................ 13
2.3. W EBTOOLS FERRAMENTAS EM AMBIENTE WEB ........................................................... 14
2.4. OUTROS COMPONENTES DO W EBSPEED ......................................................................... 23
2.5. ARQUIVOS FONTE DO W EBSPEED ................................................................................... 24
3. Arquitetura do WebSpeed
3.1.

3.2.

COMPONENTES DO W EBSPEED ...................................................................................... 25


3.1.1. Distribuio dos Componentes no WebSpeed ............................................... 25
3.1.2. Produtos do WebSpeed Transaction Server .................................................. 26
GERENCIAMENTO DE REQUISIES PELO W EBSPEED ...................................................... 26

4. Exemplos de Objetos WEB


4.1.

4.2.
4.3.

4.4.
4.5.

5.2.

5.3.
5.4.

30

TIPOS DE OBJETOS WEB ............................................................................................... 30


4.1.1. Objeto HTML Padro ...................................................................................... 30
4.1.2. Embedded SpeedScript .................................................................................. 30
4.1.3. CGI Wrapper ................................................................................................... 31
4.1.4. HTML Mapeados ............................................................................................. 31
4.1.5. Critrio de Uso ................................................................................................ 31
EXEMPLOS DE OBJETOS WEB ........................................................................................ 32
4.2.1. URLs para o Objeto WEB e PROPATH ......................................................... 32
EXEMPLOS DE EMBEDDED SPEEDSCRIPT ........................................................................ 32
4.3.1. QUERY Simples .............................................................................................. 32
4.3.2. Gerenciando a Entrada de Dados .................................................................. 34
CGI W RAPPER ............................................................................................................... 37
HTML MAPPING............................................................................................................. 39
4.5.1. HTML Mapping Simples .................................................................................. 39
4.5.2. HTML Mapping e SDO .................................................................................... 39

5. SpeedScript
5.1.

25

41

SIMILARIDADE - SPEEDSCRIPT E 4GL PROGRESS ............................................................ 41


5.1.1. Similaridade .................................................................................................... 41
5.1.2. Diferenas ....................................................................................................... 41
SINTAXES E ELEMENTOS DO SPEEDSCRIPT ..................................................................... 42
5.2.1. Executando Procedures e Objetos WEB ........................................................ 44
5.2.2. Blocos e Contextos ......................................................................................... 45
5.2.3. Contexto do Bloco e Escopo ........................................................................... 45
5.2.4. Tempo de Compilao X Tempo de Execuo .............................................. 46
PREPROCESSADORES DO W EBSPEED ............................................................................. 47
APIS DO W EBSPEED ..................................................................................................... 47

ndice

5.5.
5.6.

5.7.

5.8.
5.9.

5.4.1. Gerenciamento de Mensagens ....................................................................... 47


5.4.2. Passando Informaes entre Requisies WEB ............................................ 48
5.4.3. Troca Geral de Informao ............................................................................. 50
5.4.4. Gerenciamento de Datas e Informao de Tempo ......................................... 51
5.4.5. Gerando Cabealhos da Pgina WEB ............................................................ 51
5.4.6. Checando Opes de Configuraes ............................................................. 52
EMBEDDED SPEEDSCRIPT .............................................................................................. 52
COMO COLOCAR SPEEDSCRIPT NO HTML ...................................................................... 53
5.6.1. Comandos de Escape ..................................................................................... 53
5.6.2. Expresses de Escape ................................................................................... 54
CONSTRUO DE PGINAS WEB INTERAGINDO COM EMBEDDED SPEEDSCRIPT ............... 55
5.7.1. Passando Parmetros ..................................................................................... 55
5.7.2. Gerenciamento de Pginas Dinmicas com Forms ....................................... 57
DESENVOLVENDO OBJETOS WEB COM EMBEDDED SPEEDSCRIPT ................................... 62
5.8.1. Construindo Objetos WEB Embedded SpeedScript ....................................... 63
EXEMPLO COMPLETO DO EMBEDDED SPEEDSCRIPT ........................................................ 63

6. CGI Wrapper
6.1.
6.2.

6.3.

CONHECENDO O CGI W RAPPER ..................................................................................... 85


ESTRUTURA DO CGI W RAPPER ...................................................................................... 85
6.2.1. Estrutura de um CGI Wrapper ........................................................................ 85
6.2.2. Processamento do CGI Wrapper .................................................................... 86
EXEMPLO COMPLETO DO CGI W RAPPER......................................................................... 87

7. HTML Mapping
7.1.

8.2.

9.2.

9.3.

9.4.

9.5.
9.6.
9.7.

124

TRABALHANDO COM A SADA DISPLAY ......................................................................... 124


8.1.1. Sada Direta do DISPLAY ............................................................................. 124
8.1.2. Formatando a Sada com DISPLAY ............................................................. 126
ALTERANDO O FORMATO PADRO DE SADA .................................................................. 128
8.2.1. Setando um Padro para {&WEBSTREAM} ................................................. 129
8.2.2. Setando Atributos Padres no HTML ........................................................... 129

9. Controlando Transaes WebSpeed


9.1.

102

HTML MAPPING........................................................................................................... 102


7.1.1. HTML Mapping Simples ................................................................................ 102
7.1.2. Novas Funcionalidades no HTML Mapping .................................................. 110
7.1.3. HTML Mapping usando SDO ........................................................................ 116

8. Gerenciando Sada com DISPLAY


8.1.

85

131

ESTADOS NO W EBSPEED ............................................................................................. 131


9.1.1. Estados dos Objetos WEB ............................................................................ 131
9.1.2. Aplicaes WebSpeed usando os Estados .................................................. 131
9.1.3. Vantagens e Desvantagens do State-persistent ............................................. 132
ENTENDENDO O CONTROLE DE TRANSAO NO W EBSPEED .......................................... 132
9.2.1. Como Fazer um Objeto Web State-aware .................................................... 133
9.2.2. Objetos WEB no Contexto de Stateless e State-persistent .......................... 134
OBJETOS WEB PRIMRIOS E SECUNDRIOS ................................................................. 134
9.3.1. Executando Objetos WEB Primrios e Secundrios .................................... 135
9.3.2. Objetos WEB State-aware e Persistence ..................................................... 136
IMPLEMENTAO DO CONTROLE DE TRANSAO ........................................................... 136
9.4.1. Modificando a Procedure outputHeader ....................................................... 137
9.4.2. Modificando a Procedure process-web-request ........................................... 137
9.4.3. Sobrescrevendo Procedures e Funes ....................................................... 138
9.4.4. Modificando a Lista de Atributos ................................................................... 138
9.4.5. Modificando a Lista de Campos do Usurio ................................................. 138
CONTROLE DE TRANSAO USANDO EMBEDDED SPEEDSCRIPT ..................................... 139
CONTROLE DE TRANSAO USANDO CGI W RAPPER ..................................................... 139
CONTROLE DE TRANSAO USANDO HTML-MAPPING ................................................... 139

ndice

9.8.

9.7.1. Entendendo o process-web-request no HTML-Mapping .............................. 140


9.7.2. Modificando a Lgica de Requisio ............................................................ 141
9.7.3. Movendo os Dados Atravs do HTML-Mapping ........................................... 142
9.7.4. Criando as Definies ................................................................................... 144
9.7.5. Modificando o Main Block ............................................................................. 145
9.7.6. Customizando Campos no Control Handlers ................................................ 146
GERENCIANDO O TIME-OUT DO STATE-AWARE .............................................................. 149
9.8.1. Usando o Atributo Web-Timeout-Handler ..................................................... 149
9.8.2. Resetando o Tempo do Time-Out do Objeto WEB ...................................... 150

10. Controlando Transaes no Banco de Dados

151

10.1.
10.2.
10.3.
10.4.

ESCOPO DE UMA TRANSAO ....................................................................................... 151


SUB-TRANSAES ....................................................................................................... 153
CONTROLANDO O INCIO E FIM DE UMA TRANSAO ....................................................... 153
COMPONENTES DO SPEEDSCRIPT E TRANSAES ......................................................... 154
10.4.1. Sub-Procedures ............................................................................................ 154
10.4.2. I/O de Arquivos ............................................................................................. 154
10.4.3. Variveis dos Programas .............................................................................. 155
10.5. TRANSAES NAS APLICAES .................................................................................... 155
10.5.1. Aplicaes com Mltiplos Bancos de Dados ................................................ 155
10.5.2. Aplicaes Distribudas ................................................................................. 156
10.6. DETERMINANDO QUANDO TRANSAES ESTO ATIVAS.................................................. 156
10.7. TRANSAES EM MLTIPLAS PGINAS .......................................................................... 156
10.7.1. Gerenciamento de Transaes com Mltiplas Pginas ............................... 156
10.7.2. Trabalhando com Transaes de Mltiplas Pginas .................................... 157
10.7.3. Guia para Uso da Transao com Mltiplas Pginas ................................... 159
11. Executando Aplicaes

161

11.1. SETANDO O AMBIENTE DA APLICAO ........................................................................... 161


11.1.1. Criando o Diretrio de Trabalho da Aplicao .............................................. 161
11.1.2. Movendo a Aplicao para o Diretrio Correto ............................................. 161
11.1.3. Compilando Objetos WEB ............................................................................ 162
11.1.4. Tornando sua Aplicao Segura ................................................................... 163
11.2. INICIANDO E PARANDO UMA APLICAO......................................................................... 163
11.3. DEBUGANDO APLICATIVOS NO W EBSPEED .................................................................... 163
11.3.1. Adicionando debug=on para URL ................................................................. 163
11.3.2. Debugando com Cookies .............................................................................. 164
11.3.3. Chamando o Debugador Virtual do Objeto WEB ......................................... 164
11.3.4. Debugando e Opes Administrativas .......................................................... 164
11.3.5. Utilizando o Debugador na Aplicao ........................................................... 166
11.3.6. Arquivos de LOGs do Broker e Agentes ...................................................... 166

Prefcio

Prefcio
OBJETIVO
Introduz o aluno ao ambiente web, passando nosso conhecimento de como utilizar as
ferramentas inclusas no AppBuilder do WebSpeed, bem como os trs mtodos de criao de
pginas HTML, fornecidos pelo WebSpeed. Incluir tambm as tcnicas normalmente
utilizadas para aperfeioar seu aplicativo em relao migrao para o cdigo de reutilizao
dos aplicativos j existentes.

TIPOGRAFIA
Fontes em negrito
Comando ou caracter que o usurio edita
nfase em uma palavra ou expresso especfica

Fonte Itlica
Argumentos de programao
Comentrios no cdigo fonte
Novos termos
Ttulos das publicaes

Fonte Couriew
Exemplos de Cdigos
Nome de arquivos e pastas especficas

PALAVRAS EM LETRAS MAISCULAS


Expresses usadas para indicar termos com funes especficas ou teclas de atalhos
Exemplo: END-ERROR, GET, GO, ALT, CTRL, SPACEBAR, TAB

Combinaes De Teclas
Quando utilizado duas ou mais teclas simultaneamente, isto , quando ser preciso
pressionar uma tecla, manter esta tecla pressionada e pressionar a outra.
Exemplo: CLTR-X
Duas teclas usadas uma em seguida da outra.
Exemplo: ESCAPE H

Prefcio

OBSERVAES EM SINTAXES
As sintaxes desta apostila seguem a seguinte conveno:
As palavras-chaves estaro escritas em letras maisculas e opes ou argumentos
estaro em itlico:
SINTAXE
ACCUM aggregate expression
No exemplo acima, a palavra ACCUM uma palavra-chave. As palavras aggregate e
expression so as opes definidas para a funo ACCUM no PROGRESS Language
Reference.
Colchetes em volta de um item indicam que so opcionais:
SINTAXE
DISPLAY

STREAM stream

] [ unless-hidden ] [ no-error ]

Mas cuidado, em alguns casos, os colchetes no so observao, mas parte da linguagem.


Neste caso ela estar impressa normalmente, com a mesma fonte do restante do texto,
conforme vemos a seguir:
SINTAXE
INITIAL [ constant

, constant

Chaves em volta de um item indicam que esse item obrigatrio:


SINTAXE

BY expression

[ DESCENDING ] }

No exemplo, voc dever usar o BY e expression e a especificao DESCENDING ser


opcionalmente.
Em alguns casos, as chaves no so observaes para o leitor, mas parte da linguagem. Neste
caso ela estar impressa normalmente, com a mesma fonte do restante do texto, conforme
vemos a seguir:
SINTAXE
{&argument-name}
Barra vertical entre dois ou mais itens indica opo de escolha:
SINTAXE
PRESELECT

[ EACH | FIRST | LAST ] record-phrase

No exemplo, EACH, FIRST e LAST so opes e voc poder escolher entre uma delas. J no
exemplo abaixo, voc dever escolher um dos itens logical-name ou alias
SINTAXE

Prefcio

CONNECTED (

{ logical-name | alias } )
...

Reticncias (
) indicam que voc pode atribuir um ou mais itens alm dos
apresentados. Se um grupo de itens est entre chaves e seguido de reticncia, voc
dever escolher um ou mais dos itens. Se um grupo de itens est entre colchetes e
seguidos por reticncias, voc pode opcionalmente escolher um ou mais itens:
SINTAXE
MAXIMUM ( expression , expression

[,

expression

])

No exemplo acima, voc dever incluir duas expresses, mas pode opcionalmente incluir mais.
Note que cada expresso subseqente deve estar precedida de vrgula.
SINTAXE
MESSAGE

{ expression | SKIP [ (n)]}...

J neste exemplo, dever especificar a mensagem com a opo expression ou SKIP e


opcionalmente atribuir valor a este item
Em alguns casos, a sintaxe muito longa e no cabe na mesma linha, ento poder
acontecer de cada item estar entre seu prprio colchete em mltiplas linhas.
SINTAXE
WITH

[ ACCUM max-length ][ expression DOWN ][ CENTERED ]


[ DOWN ][ n COLUMNS ][SIDE-LABELS][ STREAM-IO]

No exemplo, as opes esto em linhas diferentes, mas se referem mesma funo WITH.

Prefcio

REFERNCIAS BIBLIOGRFICAS
Princpios Bsicos
PROGRESS Database Administration Guide and Reference
PROGRESS Installation Notes Version 9
PROGRESS Update Bulletin
PROGRESS /400 DataServer Installation Notes
PROGRESS Application Development Environment Getting Started
PROGRESS Language Tutorial
PROGRESS Master Glossary
Welcome to PROGRESS

Ferramentas de Desenvolvimento
PROGRESS AppBuilder Developers Guide
PROGRESS Basic Database Tools
PROGRESS Basic Development Tools
PROGRESS Debugger Guide
PROGRESS Help Development Guide
PROGRESS Translation Manager Guide
PROGRESS Visual Translator Guide

Ferramentas de Relatrios
PROGRESS Report Builder Deployment Guide
PROGRESS Report Builder Tutorial
PROGRESS Report Builder Users Guide
PROGRESS RESULTS Users Guide

4GL
Building Distributed Applications Using the PROGRESS AppServer
PROGRESS External Program Interfaces
PROGRESS Internationalization Guide
PROGRESS Language Reference
PROGRESS Programming Handbook
PROGRESS Database Administration Guide and Reference

DataServers
PROGRESS DataServer Guides
System Administration
PROGRESS System Administration Guide
PROGRESS System Administration Reference

SQL/Open Access
PROGRESS Embedded SQL Guide and Reference
PROGRESS Open Client Developers Guide
PROGRESS SQL Guide and Reference

SQL-92
PROGRESS Embedded SQL-92 Guide and Reference
PROGRESS JDBC Driver Guide
PROGRESS ODBC Driver Guide
PROGRESS SQL-92 Guide and Reference

Deployment
PROGRESS Developers Toolkit
PROGRESS Portability Guide

Reference
Pocket

PROGRESS

INTRODUO

1. Introduo
Especificamente, este curso descreve:
A criao de uma pgina na Web com texto e imagens.
Organizao de dados com tabelas do HTML.
Organizao de pginas na web com HTML frames.
Transferncia de dados de uma pgina para outra utilizando a URL.
Manipulao de eventos.
Como Interagir com o usurio atravs de janelas alert, prompt e confirm.
Descrever e instalar a arquitetura e a configurao do WebSpeed.
Criar pginas de HTML utilizando os trs mtodos fornecidos pelo WebSpeed.
Embedded SpeedScript;
CGI-Wrapper
HTML Mapping.

FERRAMENTAS DO WEBSPEED

2. Ferramentas do WebSpeed
O ambiente de desenvolvimento do WebSpeed possui diversos recursos, ferramentas e
componentes para a construo de pginas WEB dinamicamente, permitindo assim que a
criao dos aplicativos para WEB seja feitos de forma produtiva.

2.1. APPBUILDER
O AppBuilder o ambiente de desenvolvimento para ambientes caracter, Client/Server e para
HTML-based (ambiente WEB). Em uma mesma ferramenta possvel desenvolver os
aplicativos para qualquer que seja o ambiente desejado.
Esta ferramenta pode ser encontrada nas licenas Progress para:
WebSpeed: Criar, testar e desenvolver objetos WEB
Provision: Criar, testar e desenvolver aplicativos Client/Server multi-camadas
Provision Plus: Criar, testar e desenvolver aplicativos tanto em ambientes Client/Server
como em ambientes WEB, alm de integrao com outros aplicativos no Progress como
Java e ActiveX.

2.1.1. Desenvolvimento Grfico e Procedural


O uso do Provision permite o desenvolvimento dos aplicativos utilizando objetos grficos como
botes, campos de edio (Fill-in), combo-boxes, radio-sets, toggle-boxes entre outros.
Entretanto para desenvolver graficamente possvel apenas para ambiente Client/Server.
O WebSpeed necessita de um ambiente procedural, onde existem SpeedScript que baseado
no Progress 4GL, CGI Wrapper e objetos WEB HTML-Mapping.

2.1.2. SmartDataObjects
O WebSpeed compatvel com o SmartObject SmartDataObject, sendo este escrito para
gerenciar as regras de negcio e acesso ao banco de dados como leituras, cadastros e
validaes. Portanto, esse objeto no foi desenvolvido para permitir interface com o usurio,
mas para ser o objeto de dados, criando a interface entre a pgina WEB e o banco de dados.

2.1.3. Templates e Wizards


Para a construo de novos programas, existem ferramentas que otimizaro o processo.
Templates so os objetos bsicos para o desenvolvimento de programas e aplicaes. So
modelos pr-construdos com as funcionalidades mais bsicas dos objetos, ou seja, com as
funes que so comuns a todos os objetos de um mesmo tipo. Caso as Templates sejam
alteradas, somente os novos Masters construdos a partir deste momento recebero esta nova
implementao. Ao selecionar um novo programa a ser criado, o Progress listar todas as
templates existentes de acordo com o tipo da licena Progress instalada. No caso do Provision
Plus, todos os tipos de templates possveis como Caracter, SmartObjects, Procedurais e WEB
estaro disponveis.

FERRAMENTAS DO WEBSPEED

O Wizard a capacidade de algumas templates de direcionar a criao do aplicativo,


auxiliando no processo passo a passo at a sua concluso, e na escolha de itens e situaes.
O aplicativo resultante o mnimo necessrio para o funcionamento normal do aplicativo.
Tanto a Template pronta, como o uso de um Wizard, permitem a criao de um programa
automaticamente, sem que uma nica linha HTML de cdigo seja escrita manualmente.
Blank: Template que possui tags HTML, incluindo uma seo para SpeedScript.
CGI Wrapper: Template usado para criar um cdigo HTML dinamicamente usando
SpeedScript
Detail: Template que usa o Wizard para auxiliar na construo de uma interface WEB,
possibilitando o uso de um form para atualizar dados, alm de conexo com o banco de
dados ou uso de SDOs. O resultado um programa HTML
Frameset: Template que possui tags HTML com abertura de 3 frames ou mostra uma
mensagem quando o browser usado no suporte o uso de frames.
HTML Mapping: Template que usa o Wizard para auxiliar no mapeamento de um
arquivo HTML existente com campos de tabelas dos bancos de dados.
Main: Uma pgina de texto esttica para uma aplicao WebSpeed.
Report: Template que usa o Wizard para auxiliar na criao de um relatrio em
WebSpeed, indicando tabelas e campos a serem usados.
Report Template: Template que possui tags HTML com preprocessadores definidos
para auxiliar na construo de um aplicativo de relatrio.
Table: Template que possui tags HTML, incluindo uma seo para SpeedScript para
possibilitar a gerao de uma pgina WEB.

2.1.4. Editores de Texto


possvel utilizar diversos editores de texto para criar ou alterar programas criados pelo
AppBuilder. O Section Editor a ferramenta utilizada pelas Templates para possibilitar a
separao em sees dos aplicativos criados, facilitando a localizao dos pontos para inserir
cdigos.
Ainda possvel utilizar o prprio Procedure Editor do Progress que mostrar todo o programa
em sua rea de edio e ainda o prprio NotePad do Windows. Entretanto esse no ter os
recursos dos editores do Progress, como compilao e teste de sintaxe, mas o seu uso no
necessita de um ambiente Progress iniciado, o que ocorre nos outros casos.

2.2. EXECUTANDO O WEBSPEED NO APPBUILDER


O Progress utiliza a mesma ferramenta AppBuilder para desenvolver objetos em Client/Server
e para WEB. Entretanto necessrio configurar o ambiente para que o WebSpeed esteja
disponvel para ser acessado.

2.2.1. Configurao do WebSpeed


AdminServer
NameServer
Database Server
WebSpeed Broker
Web Server

FERRAMENTAS DO WEBSPEED

2.2.2. Identificando o Browser Padro e o Broker do


WebSpeed
Para execuo dos programas criados pelo WebSpeed necessrio identificar qual ser o
browser padro onde os aplicativos sero executados e testados e tambm identificar qual o
Broker do WebSpeed que ser utilizado. Isto feito colocando o nome do executvel do
browser e do Broker no AppBuilder.
Para configurador o nome do browser a ser usado e do Broker, necessrio selecionar no
menu do AppBuilder a opo Options e depois Preferences. A janela Preferences ser aberta:

Selecionar a pasta WebSpeed e colocar no campo Web-Browser o nome do executvel,


inclusive o caminho completo, do browser que ser usado. Por exemplo:
NETSCAPE: c:\program files\netscape\communicator\program\netscape.exe
INTERNET EXPLORER: c:\program files\plus!\microsoft internet\iexplorer.exe
O campo Broker URL deve informar o URL usado para acessar o Broker do WebSpeed que
executar os objetos WEB. Por exemplo:
http://host_name[:port]/scripts_dir/messenger/WService=broker
Onde:
host_name: Identifica o nome da mquina que executa o Web Server.

FERRAMENTAS DO WEBSPEED

port: Identifica o nmero da porta do Web Server. Pode ser opcional caso o Web Server use a
porta padro que a 80.
scripts_dir: Identifica o diretrio de Scripts do Web Server para os Messengers CGI ou ISAPI.
Caso o Messenger NSAPI estiver sendo usado, essa opo pode ser omitida.
messenger: Identifica o nome do Messenger. No caso do Messenger CGI, necessrio
colocar o nome do executvel. No caso do Messenger ISAPI ou NSAPI deve ser informado o
arquivo DLL.
Broker: Identifica o nome do Broker.
O boto Test ir verificar se a conexo com o Broker est correta.

Para desenvolver aplicativos para WEB necessrio identificar o Broker do WebSpeed no


AppBuilder. Este Broker deve conectar os mesmos bancos de dados que o AppBuilder.
Lembrando que no ambiente de desenvolvimento os bancos de dados usados pelo aplicativo
devem estar conectados, permitindo assim sua compilao e checagem de sintaxe.

2.2.3. Setando o Modo de Desenvolvimento


O ambiente de desenvolvimento pode estar no prprio servidor, onde o WebSpeed Server est
instalado. Para isso algumas consideraes devem ser levadas em conta:
O AppBuilder estar sendo executado na mesma mquina que o WebSpeed Server.
Tanto o AppBuilder quanto o WebSpeed Server devem ter o mesmo diretrio de
trabalho e PROPATH.

FERRAMENTAS DO WEBSPEED

No caso de desenvolvimento remoto, isto , o desenvolvimento ser feito em uma mquina


diferente de onde exista o WebSpeed Server, pode-se usar o AppBuilder, mas com algumas
caractersticas prprias:
O PROPATH do Progress usado no ambiente remoto e do servidor devem ser
diferentes.
O diretrio de trabalho do WebSpeed Server deve ser diferente do ambiente remoto.
Os programas usados, salvos e compilados sero gravados nos diretrios do
WebSpeed Server.
Para preparar o AppBuilder para trabalhar remotamente necessrio clicar no boto Switch to
Remote Development para que o AppBuilder trabalhe como ambiente remoto ou clicar no
mesmo boto quando este se chamar Switch to Local Development para transformar em
ambiente local.

Modo Local

Modo Remoto

Caso exista algum problema que impea o acesso remoto do WebSpeed Server, possvel
salvar os programas localmente. Entretanto no ambiente local no possvel compilar fontes
que possuam SpeedScript.

2.3. WEBTOOLS FERRAMENTAS EM AMBIENTE WEB


O WebTools contm ferramentas do Progress mas em uma pgina WEB, permitindo acessar
dados e, apesar de mais trabalhoso, construir programas. A principal vantagem no precisar
ter instalado o WebSpeed localmente para acessar as ferramentas de desenvolvimento.
Entretanto o AppBuilder possui um ambiente de desenvolvimento mais amigvel e ainda podese acessar dele as WebTools. Para isso acessar a opo Tools no menu e depois WebTools.
A execuo dessa opo abre uma pgina da internet com o WorkShop diretamente.

FERRAMENTAS DO WEBSPEED

Esta pgina do WebTools possui um frame de detalhe com todos os links para
desenvolvimento e ajuda e um frame de trabalho.
Cada link do frame de detalhes permite o acesso a uma atividade ou informao:
Application Manager
Possui informaes do gerenciador da aplicao como quem so os servios disponveis e os
diretrios de trabalho do WebSpeed Server.

FERRAMENTAS DO WEBSPEED

Data Browser
Mostra as informaes como nome, servio e localizao dos bancos de dados conectados no
WebSpeed Server.

Editor
O editor do WorkShop funciona basicamente como o Procedure Editor do 4GL. Possui opes
para trabalhar com os arquivos e ainda checar sintaxe, criar Rcode e executar os programas.

FERRAMENTAS DO WEBSPEED

File Tools
Esta opo possibilita a pesquisa de programas e arquivos utilizando filtros. Alm de possibilitar
executar, compilar, gerar offset e eliminar arquivos.

FERRAMENTAS DO WEBSPEED

OS Command
Esta opo possibilita a informar comandos do sistema operacional.

Scripting Lab
Esta opo possibilita a realizar pequenas testes e possui pequenos cdigos exemplos. A
maior vantagem que os programas no precisam ser gerados, compilados e depois
executados.

FERRAMENTAS DO WEBSPEED

Agent Variables
Mostra as variveis correntes do ambiente atual.

FERRAMENTAS DO WEBSPEED

Database
Possui informaes sobre todos os bancos de dados conectados ao agente do WebSpeed.

Messages
Possibilita pesquisar as mensagens de erro ocasionadas no Progress e buscar por
detalhamentos. O boto Query Knowledge Base for Error permite o acesso pgina da
Progress que possui maiores informaes de erro.

FERRAMENTAS DO WEBSPEED

Object State
Mostra uma lista de todos os objetos WEB ativos com informaes como tipo do objeto e ainda
sua atual situao neste ambiente WEB.

FERRAMENTAS DO WEBSPEED

Propath
Mostra a lista de todos os diretrios usados pelo ambiente do WebSpeed.

Virtual System Tables


Mostra as estatsticas de performances existentes nessas Virtual System Tables (VST).

FERRAMENTAS DO WEBSPEED

2.4. OUTROS COMPONENTES DO WEBSPEED


Variveis Globais do WebSpeed
So variveis existentes para todo objeto WEB que est sendo executado em um mesmo
Agente, e que mantm o ambiente CGI atual e outras informaes sobre a atualizao da
pgina WEB ou transaes persistentes no WebSpeed. Estas variveis esto definidas no
instalao-progress/src/web/method/cgidefs.i.
Definies de preprocessadores no WebSpeed
Os preprocessadores so definidos para tratar consistncias no acesso para o ambiente WEB.
Estes preprocessadores esto definidos no instalao-progress/src/web/method/cgidefs.i.
Funo API
Conjunto de funes padres do WebSpeed que possui uma grande variedade de servios
para os objetos WEB. Estas funes realizam tarefas diversas como tratar URLs e retornar
valores especficos do ambiente CGI, estando todas disponveis para todas as aplicaes.
Estas funes esto definidas no instalao-progress/src/web/method/cgidefs.i.
Method Procedures
Conjunto de procedures em SpeedScript disponibilizando diversos servios para os objetos
WEB. Algumas procedures e funes (API) so duplicadas para possibilitar compatibilidade
com outras verses do WebSpeed. Algumas procedures podem ser customizadas para cada
objeto WEB. Os fontes de diversas procedures so localizadas no objeto web-util.p do diretrio
instalao-progress/src/web/objects.
Control Handlers
uma classe especial de procedures que responde a pseudos eventos nos objetos WEB
HTML-Mapping e que podem ser customizadas. Por exemplo, customizando (OVERRIDE) as

FERRAMENTAS DO WEBSPEED

procedures WEB.INPUT e WEB.OUTPUT possvel trocar o tratamento padro por outro.


Cada procedure converte os dados entre um tipo de elemento HTML e um campo SpeedScript
do tipo correspondente. Estes controles esto localizados em um utilitrio de mapeamento de
tags no instalao-progress/src/web/support.
TAGMAP.DAT
Este arquivo contm o mapeamento entre os tipos de elementos no HTML e campos nos
objetos SpeedScript. Cada entrada no arquivo inclui a localizao padro do WEB.INPUT e
WEB-OUTPUT para cada campo mapeado, podendo ainda customizar esse arquivo para criar
seus prprios mapeamentos.
WEB-DISP.P
o programa de controle que executado em todos os agentes do WebSpeed, executando
todos os objetos WEB. O fonte SpeedScript fica no instalao-progress/src/web/object,
gerenciando o estado de diversas transaes que a aplicao usa, sendo ainda includo com o
ambiente de desenvolvimento, pois a central de operaes da aplicao, afetando como e
onde deve ser setado o estado da transao nos objetos WEB. Ainda iniciado o programa
web-util.p possuindo mais funes e procedures em tempo de execuo.

2.5. ARQUIVOS FONTE DO WEBSPEED


Exemplos
Possui cdigos exemplos, incluindo HTML e OFFSETS.
Mtodos
Vrios fontes de includes SpeedScript definindo procedures e funes usados no WebSpeed.
Objetos
Possui o fonte do principal objeto WEB executando as procedures web-disp.p e web-util.p.
Support
Contm todas as procedures TAGMAP para os objetos HTML-Mapping, estando estes
especificados no arquivo tagmap.dat, possuindo tambm procedures de execuo para
debugar e interpretar os arquivos de offset pata um objeto HTML-Mapping.
Template
So os programas bases para a construo de novos objetos WEB e outros tipos de
procedures.

ARQUITETURA DO WEBSPEED

3. Arquitetura do WebSpeed
3.1. COMPONENTES DO WEBSPEED
Agente WebSpeed Processo que executa o objeto WEB, realiza transaes e
dinamicamente combina dados com o formato HTML. Basicamente um Progress 4GL
Character executado em Batch.
WebSpeed Broker Este processo pode ser dividido em:
- Registrar o servio WebSpeed fornecido para um NameServer para ser
acessado por um ou mais cliente HTML. O cliente HTML executado por um
browser.
- Gerencia conexes entre clientes e um conjunto de Agentes WebSpeed.
- Mantm o status de cada Agente neste conjunto e dinamicamente escala o
nmero de Agentes de acordo com a variao da demanda.
WebSpeed Messenger Processo que gerencia a transferncia de dados entre o
WEB Server e o Agente WebSpeed durante uma simples transao WEB. O
Messenger um programa CGI ou um processo ISAPI ou NSAPI, dependendo do
WEB Server e como planejado o desenvolvimento da aplicao.
NameServer Processo que mantm uma lista de WebSpeed Transaction Servers. O
Transaction Servers registra os servios da aplicao providas com o NameServer. O
NameServer pode diretamente requisitar a conexo de um cliente para um WebSpeed
Broker que suporta um servio de uma aplicao requisitada. Isto d uma maior
escalabilidade e transparncia da localizao da aplicao.
Quando o Enterprise Transaction Server instalado, o NameServer tambm realiza o
Load Balancing, permitindo balancear a carga do cliente entre mltiplos Brokers que
suportam um mesmo servio da aplicao, isto , o mesmo conjunto de procedures e
recursos.
WorkShop Ferramenta para desenvolver e testar as aplicaes WebSpeed.

3.1.1. Distribuio dos Componentes no WebSpeed


A figura a seguir mostra a mxima distribuio dos componentes que se pode alcanar com os
componentes do WebSpeed em uma rede, mostrando os principais componentes do modelo
run-time do WebSpeed que devem residir juntos em uma mesma mquina. O Messenger deve
estar na mesma mquina do WEB Server. O Broker e o Agente tambm ficam em uma mesma
mquina. Caso contrrio, pode-se combinar essas configuraes em qualquer combinao de
uma ou mais mquinas suportadas pelo WebSpeed.
Mquina 1
WebSpeed
WorkShop

Mquina 2
Web Server
Messenger

Mquina 3
NameServer

Mquina 4
Broker
Agente

Mquina 5
DB SERVER

Ainda possvel adicionar o Progress AppServer em qualquer mquina que possa suporta-lo
na rede. O AppServer pode esecutar procedures Progress no lugar do Agente, como um
Progress Client.

ARQUITETURA DO WEBSPEED

3.1.2. Produtos do WebSpeed Transaction Server


O WebSpeed Transaction Server deve ser visto como WebSpeed Development Server,
WebSpeed Transaction Server ou WebSpeed Enterprise Transaction Server. Todos esses
produtos so consistidos dos mesmos componentes. Entretanto, existem diferenas no nmero
de Agentes suportados para cada um, alm do que, apenas o WebSpeed Enterprise
Transaction Server suporta load balancing.
Produto
WebSpeed Developmente Server
WebSpeed Transaction Server
WebSpeed Enterprise Transaction Server

Nmero de Agentes
2
5 ou 25
50 ou 250

Load Balancing
No
No
Sim

Os 3 produtos contem essencialmente os mesmos componentes, tanto para desenvolver como


em ambiente de produo. Mas importante lembrar que em ambiente de produo pode ser
necessrio uma maior quantidade de Agentes.
O WebSpeed Enterprise Transaction Server suporta Load Balancing, aumentando a eficincia
no gerenciamento de requisies dos clientes. Load Balancing implementado permitindo o
NameServer para gerenciar mltiplos WebSpeed Transaction Servers, que podem ser
distribudos em diversas mquinas no ambiente.

3.2. GERENCIAMENTO DE REQUISIES PELO


WEBSPEED
O ciclo bsico de requisio o mesmo para o WebSpeed Development Server, WebSpeed
Transaction Server ou WebSpeed Enterprise Transaction Server. Este ciclo tambm o
mesmo para todos os tipos de objetos WEB.
1 O WEB Server recebe a requisio, uma URL, de um Browser de internet:

2 O WEB Server gera um CGI Messenger ou dispara um ISAPI ou NSAPI Messenger:

3 O Messenger envia uma requisio para o NameServer por um Broker disponvel:

ARQUITETURA DO WEBSPEED

4 O Messenger inicializa uma conexo com o Broker no endereo retornado pelo


NameServer e seguindo a requisio para o Broker:

O WebSpeed Enterprise Transaction Server pode ordenar ao NameServer gerenciar mltiplos


Brokers que suportam a mesma aplicao. A escolha do Broker ser feita baseado no Load
Balancing.
5 O Broker consulta o conjunto de Agentes e atualiza a requisio para um Agente ocioso.

ARQUITETURA DO WEBSPEED

6 O Agente e o Messenger estabelecem uma conexo. O nome do objeto WEB e o ambiente


para a requisio so passados para o Agente:

7 O Agente executa o objeto WEB. Tambm realiza as leituras e gravaes necessrias no


banco de dados, mantendo a conexo com o Messenger enquanto o objeto WEB est sendo
executado:

ARQUITETURA DO WEBSPEED

8 O Agente passa o HTML gerado para o Messenger que envia para o Browser atravs do
WEB Server:

Um objeto WEB state-aware, apesar de no ter uma execuo prolongada, mantm o contexto
persistente para execues futuras do Agente.
Aps completar a execuo, o Agente disconecta do Messenger e atualiza seu estado como
disponvel para o Broker. O WEB Server desconecta do Browser depois de enviar a pgina
WEB HTML.

EXEMPLOS DE OBJETOS WEB

4. Exemplos de Objetos WEB


A programao WEB pode ser feita utilizando diversos tipos de objetos, sejam HTML Mapping
ou CGI Wrapper. O importante lembrar que a programao WEB tem como caracterstica
principal separao da interface da regra de negcio. Sendo assim, o conceito de BUFFER
deve estar bem claro para evitar problemas nas leituras e alteraes de registros.

4.1. TIPOS DE OBJETOS WEB


Qualquer objeto WEB para o WebSpeed uma procedure (Rcode) que pode ser executado por
uma URL. Estes objetos podem tanto gerar pginas WEB, como acessar objetos de dados que
fazem o acesso aos bancos de dados, permitindo o cadastro, alterao, eliminao e leitura de
registros. Uma aplicao WEB pode ser composta de um ou mais objetos WEB. Todos os tipos
de objetos WEB so compilados e geram Rcodes onde podem ser executados pelos agentes
do WebSpeed.
Estes objetos WEB so:
HTML padro
HTML com SpeedScript
CGI Wrapper
HTML Mapeado

4.1.1. Objeto HTML Padro


Usando o WebSpeed possvel compilar praticamente qualquer programa HTML dentro de um
WEB Object. A compilao cria um arquivo .w temporrio para depois criar um Rcode. Este
Rcode cria a pgina WEB que idntica ao arquivo original HTML quando visualizado no
browser.
Um arquivo HTML pode ser executado diretamente no browser, dispensando a compilao.
Entretanto, o arquivo HTML ser executado em uma aplicao WebSpeed, em um agente do
WebSpeed, onde este agente executa apenas arquivos compilados (Rcodes). Por isto a
compilao dos arquivos HTML necessria para gerar os Rcodes. Quando este programa
executado pelo agente do WebSpeed, a sada HTML recriada.
A aplicao desenvolvida para o WebSpeed composta de objetos WEB simples e por outros
objetos WEB dinmicos. Esta combinao permitir a interao dos objetos.

4.1.2. Embedded SpeedScript


SpeedScript um subconjunto do 4GL Progress. Os objetos WEB Embedded SpeedScript so
arquivos HTML com o cdigo SpeedScript. A identificao de um cdigo SpeedScript em um
HTML feita por tags especficas que delimitam a rea usada pelo SpeedScript. A abertura da
tag :
<script language=SpeedScript>
Para encerrar o uso do SpeedScript, deve-se fazer:

EXEMPLOS DE OBJETOS WEB

</script>
A compilao do objeto WEB Embedded SpeedScript tambm gera um arquivo .W temporrio
e a partir dele um Rcode criado. Ao gerar o HTML a ser usado pelo browser, o HTML original
montado e as informaes geradas pelo SpeedScript so criadas nesse HTML.
Tanto a template Detail Wizard como a Report Wizard criam um Rcode usando o Embedded
SpeedScript em um arquivo HTML. Alm da existncia da template Blank que um arquivo
HTML com as tags para Embedded SpeedScript prontas.

4.1.3. CGI Wrapper


O cdigo fonte do objeto WEB CGI Wrapper um arquivo (.w) SpeedScript, sem estar
associado a nenhum cdigo fonte HTML. O Rcode criado pela compilao do programa fonte
(.w) executado pelo agente do WebSpeed. Quando o objeto WEB CGI Wrapper executado,
um arquivo HTML criado dinamicamente com as informaes corretas para serem mostradas
em um browser.
O CGI Wrapper utiliza o preprocessador {&OUT} na procedure interna process-web-request
para gerar uma pgina WEB (HTML) vlida. Este HTML final possui um cabealho gerado pelo
prprio CGI Wrapper.
Para usar o CGI Wrapper, existe uma template no AppBuilder prpria para isso. Esta template
possui o corpo do SpeedScript para gerar e criar um arquivo HTML para o browser.

4.1.4. HTML Mapeados


O HTML Mapeado um arquivo HTML padro com objetos para criar a interface de tela para
entrada de dados. A procedure SpeedScript (.w) mapeia esses objetos para os campos de
tabelas dos bancos de dados ou para o SmartDataObject. A compilao nesse caso gera um
arquivo de offset (.off) antes de gerar o Rcode. Este arquivo de offset mantm a localizao dos
campos no layout do HTML. O uso do template HTML Mapping Wizard auxilia ao mapear os
campos do HTML com os campos do banco de dados ou do SmartDataObject.
O HTML Mapeado til para aplicaes com atualizaes no banco de dados, pois este
tratamento nativo deste tipo de template.

4.1.5. Critrio de Uso


A escolha da template a ser usada para construir uma aplicao deve ser feita de acordo com
sua aplicao.
Para trabalhar diretamente em HTML, Embedded SeepdScrip pode ser o mais apropriado.
Para separar a interface da lgica de negcio, o uso do CGI Wrapper ou HTML Mapeado pode
ser o mais indicado.
Para construir aplicaes persistentes, pode-se usar CGI Wrapped ou HTML Mapeado.
Para cada tipo de objeto WEB existe um tipo de interao entre o HTML e a lgica de negcio.
No caso do Embedded SpeedScript e do CGI Wrapper, a combinao entre o HTML e a lgica

EXEMPLOS DE OBJETOS WEB

de negcio existe na compilao. O HTML Mapeado converge para HTML puro no momento da
execuo.
Em tempo de compilao, existe uma melhoria de performance, pois todo cdigo fica contido
em um nico arquivo, inclusive expresses SpeedScripts (strings). Entretanto, fica a limitao
de 60KB como tamanho mximo dos programas gerados. Em compensao, em tempo de
execuo dos HTML Mapeados existe uma separao entre HTML e SpeedScript,
automatizando entrada e sada de dados no HTML. Mas as geraes das pginas WEB so
mais complexas devido s interaes necessrias.

4.2. EXEMPLOS DE OBJETOS WEB


Antes de iniciar os exemplos, importante ter configurado o WebSpeed. No caso, verificar na
opo PREFERENCES localizada na opo OPTIONS do menu do AppBuilder. Na janela
aberta, verificar se o nome do browser a ser usado est correto e se o nome do Broker tambm
est correto na pasta WebSpeed.

4.2.1. URLs para o Objeto WEB e PROPATH


A URL deve indicar o nome do objeto WEB a ser executado:
http://host_name[:port]/scripts_dir/messenger/WService=broker/web_object
Onde WEB_OBJECT o nome do objeto WEB a ser executado pelo browser. Este nome deve
conter o caminho parcial para a execuo do programa, onde o agente do WebSpeed usar o
PROPATH com o qual foi executado para localizar e executar o objeto passado pela URL.

4.3. EXEMPLOS DE EMBEDDED SPEEDSCRIPT


Os programas a serem construdos podem ser criados inicialmente de arquivos vazios ou das
templates Report Wizard e Detail Wizard. As templates possuem informaes iniciais para usar
o Embedded SpeedScript.

4.3.1. QUERY Simples


Existem duas tags bsicas para o WebSpeed. A tag SCRIPT que informa qual a linguagem
que deve ser usada, que no caso SpeedScript. Esta tag identifica os comandos 4GL
(Comandos SpeedScript) que devem ser usados. Por exemplo:
<script language=SpeedScript> FOR EACH customer: </script>
Por ser um comando de abertura de um bloco, as mesmas tags deveriam ser usadas para
identificar o comando END. Ficando:
<script language=SpeedScript> END. </script>
O uso das tags nessa forma, cria um bloco de interao (FOR EACH), executando para cada
registro lido o HTML existente dentro do bloco.

EXEMPLOS DE OBJETOS WEB

A outra tag utilizada so os caracteres de crase ( `...` ). Esta tag inclui o valor corrente de cada
elemento de dados separados pelas crases, diretamente no HTML.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Listagem de Customer</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<h1>Listagem de Customer</h1>
<table border>
<tr>
<th>Cliente</th>
<th>Nome</th>
<th>Telefone</th>
</tr>
<SCRIPT LANGUAGE="SpeedScript">
FOR EACH customer NO-LOCK:
</SCRIPT>
<tr>
<td align=left>`customer.custnum`</td>
<td align=left>`customer.name`</td>
<td align=left>`customer.phone`</td>
</tr>
<SCRIPT LANGUAGE="SpeedScript">
END.
</SCRIPT>
</table>
</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo4/exemplo01.html

Este programa gera uma pgina WEB com uma tabela de trs colunas. Cada linha tem 1
registro da tabela de Customer impresso com os campos CUSTNUM, NAME e PHONE.

EXEMPLOS DE OBJETOS WEB

4.3.2. Gerenciando a Entrada de Dados


O Embedded SpeedScript possibilita o gerenciamento de entrada de dados na pgina WEB.
Isso permite a interao do usurio com a pgina WEB.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Pesquisa de Customer</TITLE>
</HEAD>
<BODY>
<H1>Dados de Customer</H1>
<!--WSS IF get-value("custnum") <> "" THEN
FIND customer WHERE customer.custnum = INTEGER(get-value("custnum"))
NO-LOCK NO-ERROR. -->
<TABLE>
<FORM NAME="form1" ACTION="exemplo%2Fcapitulo4%2Fexemplo02.html"
METHOD="POST">
<TR>
<TD>Entre com<BR>Customer:</TD>
<TD><INPUT NAME="CustNum" SIZE="20"
VALUE=`IF AVAILABLE customer THEN STRING(customer.custnum)
ELSE ""`></TD>
<TD COLSPAN="2"><INPUT TYPE="SUBMIT" NAME="BUTTON" VALUE="Procurar"></TD>
</TR>
<TR><TD COLSPAN="4"><HR></TD></TR>
<!--WSS IF AVAILABLE customer THEN DO: -->
<TR>

EXEMPLOS DE OBJETOS WEB

<TD>Nome:</TD>
<TD><INPUT NAME="name" SIZE="20" VALUE="`customer.name`"></TD>
<TD>Telefone:</TD>
<TD><INPUT NAME="phone" SIZE="20" VALUE="`customer.phone`"></TD>
</TR>
<TR>
<TD>Primeiro Endereo:</TD>
<TD COLSPAN="3"><INPUT NAME="address" SIZE="20"
VALUE="`customer.address`"></TD>
</TR>
<TR>
<TD>Segundo Endereo:</TD>
<TD COLSPAN="3"><INPUT NAME="address2" SIZE="20"
VALUE="`customer.address2`"></TD>
</TR>
<TR>
<TD>Cidade:</TD>
<TD><INPUT NAME="city" SIZE="20" VALUE="`customer.city`"></TD>
<TD>CEP:</TD>
<TD><INPUT NAME="postalcode" SIZE="20" VALUE="`customer.postalcode`"></TD>
</TR>
<TR>
<TD>UF:</TD>
<TD COLSPAN="3"><INPUT NAME="state" SIZE="20"
VALUE="`customer.state`"></TD>
</TR>
<TR>
<TD>Comentrios:</TD>
<TD><TEXTAREA NAME="comments"
ROWS="5" COLS="30">`customer.comments`</TEXTAREA></TD>
</TR>
<!--WSS END. -->
</FORM>
</TABLE>
</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo4/exemplo02.html

Este programa ir abrir um campo de edio para o cdigo de Customer e um boto de


pesquisa. Ao clicar o boto, ser realizada uma verificao se o campo de edio possui um
valor diferente de vazio. Caso sim, ser realizada uma pesquisa na tabela para buscar os
dados necessrios para mostrar o registro.

EXEMPLOS DE OBJETOS WEB

Na tag <!WSS o comando GET-VALUE l o valor digitado no campo habilitado no browser.


O GET-VALUE uma funo da API do WebSpeed, retornando o valor do objeto nomeado
como CUSTNUM.
O SpeedScript usado basicamente duas vezes. Na primeira verifica se o valor lido do campo
diferente de vazio e depois usa o comando FIND para pesquisar o valor do registro. Depois
usado novamente para analisar se o cdigo informado est disponvel (AVAILABLE). Caso
esteja, montado um HTML de sada com os campos a serem mostrados. Entretanto, uma
terceira vez acaba sendo necessria usar o SpeedScript, pois o comando IF usado abre um
bloco com o comando DO, sendo necessrio fechar esse bloco com o comando END.
importante ressaltar, que toda leitura dos valores dos campos colocados para a entrada de
dados, retornam um valor no tipo caracter. Sendo assim, o tipo do campo usado no FIND
existente no SpeedScript deve ser convertido no tipo correspondente ao do campo pesquisado.
No exemplo, o tipo o inteiro e a funo usada a INTEGER.

EXEMPLOS DE OBJETOS WEB

4.4. CGI WRAPPER


O CGI Wrapper contm uma procedure chamada PROCESS-WEB-REQUEST. Esta procedure
inicia a sada para o BROWSER, provendo tags HTML necessrias para completar uma pgina
HTML vlida.
PROCEDURE process-web-request :
/*---------------------------------------------------------------------------Purpose:
Process the web request.
Parameters: <none>
Notes:
----------------------------------------------------------------------------*/
RUN outputHeader.
{&OUT}
'<HTML>':U SKIP
'<HEAD>':U SKIP
'<TITLE> Listagem de Customer </TITLE>':U SKIP
'</HEAD>':U SKIP
'<BODY BGCOLOR="#FFFFFF">':U SKIP.
{&OUT}
'<H1> Listagem de Customer </H1>':U SKIP
'<TABLE BORDER="1">':U SKIP
'<TR>':U SKIP
' <TH> Cliente </TH>':U SKIP
' <TH> Nome
</TH>':U SKIP
' <TH> Telefone </TH>':U SKIP
'</TR>':U SKIP.

EXEMPLOS DE OBJETOS WEB

FOR EACH customer NO-LOCK:


{&OUT}
'<TR>':U SKIP
' <TD ALIGN="left">':U customer.custnum '</TD>':U SKIP
' <TD ALIGN="left">':U customer.NAME
'</TD>':U SKIP
' <TD ALIGN="left">':U customer.phone
'</TD>':U SKIP
'</TR>':U SKIP.
END.
{&OUT}
'</TABLE>':U SKIP
'</BODY>':U SKIP
'</HTML>':U SKIP.
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo4/exemplo03.w

Neste exemplo, a procedure PROCESS-WEB-REQUEST cria toda pgina WEB que satisfaz a
requisio, incluindo todo HTML e dados associados. Primeiramente a procedure OUTPUTHEADER executada para gerar o cabealho HTTP da pgina. Aps isto, uma tabela
montada apresentando o cdigo, nome e telefone de cada registro de CUSTOMER. A
construo dessa tabela feita pelo comando FOR EACH. O resultado final mostrado em
forma de uma tabela, semelhante ao exemplo do SpeedScript.
Para a criao de um objeto WEB CGI Wrapper, existe uma template prpria para isso com o
mesmo nome, CGI Wrapper.
O preprocessador {&OUT} uma sintaxe do WebSpeed que inicia a sada para uma pgina
WEB. Este preprocessador identifica o STREAM de sada, indicando ser uma sada apontada
como WEB.

EXEMPLOS DE OBJETOS WEB

4.5. HTML MAPPING


Enquanto um programa desenvolvido como SpeedScript um HTML e um programa
desenvolvido como CGI Wrapper um programa Progress, o HTML Mapping utiliza os dois
tipos de arquivos, separando a interface do HTML da procedure que interage com os dados.
Esta interao entre HTML e Progress feita por um arquivo criado aps o mapeamento com
extenso .OFF.
Uma procedure chamada htmOffSets criada no HTML Mapping, sendo responsvel pela
associao entre os campos do formulrio do HTML e os campos do banco de dados.

4.5.1. HTML Mapping Simples


Este cdigo no possui nenhum SpeedScript embutido, um HTML com um form para entrada
e impresso de dados. Para a comunicao com este HTML, pode-se usar o HTML Mapping
Wizard do AppBuilder. Este template possibilita o mapeamento entre os HTMLs:
Mapear cada campo do tipo INPUT e TEXTAREA com os equivalentes FILL-IN e
EDITOR do banco de dados.
Cria um arquivo OFFSET especificando a posio no form do HTML que mostrado ao
cliente.
Na procedure process-web-request adicionado o comando FIND, como um
SpeedScript.
Salvar o cdigo fonte com o mesmo nome do HTML, mas usando a extenso W.

4.5.2. HTML Mapping e SDO


Alm do mapeamento diretamente com o banco de dados, o mesmo pode ser feito com as
SmartDataObjects (SDO). A diferena principal a fonte onde esto os campos, apenas
substituindo o banco de dados pela SDO.
necessrio apenas criar a SDO desejada com a tabela e os campos a serem trabalhados no
HTML Mapping. Nos dois casos, o importante desenhar inicialmente o HTML.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Localizar Customer</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<H1>Detalhes de Customer</H1>
<FORM ACTION="exemplo%2Fcapitulo4%2Fexemplo04.html" METHOD="POST">
<P>
Entre com Customer: <INPUT NAME="custnum" SIZE="5">
<INPUT TYPE="SUBMIT" NAME="button" VALUE="Localizar"><BR><BR>
Nome: <INPUT NAME="name" SIZE="20">
--------Telefone: <INPUT NAME="phone" SIZE="20"><BR><BR>
Endereo 1: <INPUT NAME="address" SIZE="20"><BR>
Endereo 2: <INPUT NAME="address2" SIZE="20"><BR><BR>
Cidade: <INPUT NAME="city" SIZE="12">
---Estado: <INPUT NAME="state" SIZE="20">
---Cep: <INPUT NAME="postalcode" SIZE="10"><BR><BR>
Comentarios: <TEXTAREA NAME="comments" ROWS="2" COLS="30"></TEXTAREA>

EXEMPLOS DE OBJETOS WEB

</p>
</FORM>
</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo4/exemplo04.html

O resultado desse HTML fica como:

SPEEDSCRIPT

5. SpeedScript
5.1. SIMILARIDADE - SPEEDSCRIPT E 4GL PROGRESS
O SpeedScript utilizado para desenvolver aplicaes em ambiente WEB, sendo este uma
implementao do Progress 4GL. O conceito bsico do Progress 4GL deve ser obedecido no
uso do SpeedScript.

5.1.1. Similaridade
Regras de escopo e estrutura de blocos.
Eventos do banco de dados como CREATE e DELETE de registros.
Regras de LOCK de registros e transaes.
Uso das SmartDataObjects como fontes de dados.
Uso do AppServer para requisitar processos.
Pode ser desenvolvido usando o AppBuilder.

5.1.2. Diferenas
Programas escritos em 4GL so normalmente STATE-AWARE, enquanto aplicaes
em SpeedScript so STATELESS (sem estado), onde:
- STATE-AWARE: Mantm o contexto enquanto houver conexo do Client com o
agente. Como uma extenso do Progress Client, mantendo o escopo das variveis
e Locks de registros e transaes.
- STATELESS: Cada acesso ao Agent cria uma nova sesso Client do Progress.
Com isso todos os escopos de variveis e registros so novos.
Eventos de objetos grficos (GUI) no usados no SpeedScript, pois so gerenciados
pelo HTML.
O preprocessador {&OUT} usado para indicar a sada de dados para uma pgina
HTML.
O bloco do processo de I/O para WEB semelhante ao 4GL, mas comandos como
UPDATE e PROMPT-FOR, alm de MESSAGE (VIEW-AS ALERT-BOX) e PAUSE no
podem ser usados ou so simplesmente ignorados.
So poucos os eventos que podem ser disparados em ambientes WEB. As triggers de
bancos de dados funcionam sem problemas, e o evento essencial no SpeedScript o
WEB-NOTIFY. Entretanto, normalmente usado apenas pelo programa de controle de
agentes (WEB-DISP.P). Sendo assim, o comando WAIT-FOR no pode ser usado.
Algumas procedures esto disponveis em arquivos Includes e so acessados pelo
boto Insert Call no Section Editor, sendo apropriados apenas em aplicaes
WebSpeed:
-

getWebState
getWebTimeRemaining
hidden-field-list
set-cookie
get-cookie

Existem dois arquivos, admweb.i e html-map.i, que contm as chamadas apropriadas


apenas para o uso em WebSpeed.

SPEEDSCRIPT

SpeedScript possui algumas extenses especiais, incluindo o dispositivo de sada WEB


virtual (WEB) para definir a STREAM de sada da pgina WEB para o servidor WEB e
o sistema de WEB-CONTEXT para acessar o ambiente de requisies. Entretanto,
essas extenses esto em APIs ou includes definidas pelo WebSpeed. O uso dos
preprocessadores {&OUT} e {&DISPLAY} ajudam a direcionar a sada para o padro
WEB. Essas definies esto na include instalao-progress/src/web/method/cgidefs.i.

5.2. SINTAXES E ELEMENTOS DO SPEEDSCRIPT


SpeedScript um bloco estruturado, comando a comando, onde, o comportamento da
Aplicao WebSpeed depende da organizao dos comandos dentro dos blocos. Entretanto,
as unidades bsicas de execuo das aplicaes do WebSpeed so as linhas de comandos.
Linhas de Comandos
A sintaxe utilizada no SpeedScript a mesma utilizada no 4GL. As linhas de comando so
finalizadas por ponto (.) e os blocos so terminados com dois pontos (:).
O SpeedScript no case-sensitive, mas, por conveno, as palavras-chaves e
preprocessadores do SpeedScript so colocadas em letras maisculas. As variveis de
ambiente CGI definidas no SpeedScript so expressas em maisculas, entretanto,
comparaes com textos e queries de banco de dados podem ser case-sensitive, dependendo
do contexto e especificaes de comparao e query.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Exemplo de SpeedScript</TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="SpeedScript">
/*-----------------------------------------------------------------File:
Description:
Created:
-------------------------------------------------------------------*/
{&OUT} '<H1> Primeiro exemplo usando SpeedScript! </H1>'.
</SCRIPT>
</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo5/exemplo05.html

Este exemplo possui apenas o {&OUT} para realizar a sada da informao na pgina WEB,
identificada como linguagem SpeedScript.
Ainda possvel visualizar esse cdigo pelo WorkShop. Para isto, basta acessar WebTools na
opo Tools do menu. No WorkShop aberto, acessar Scripting Lab. Na rea aberta para
edio, colocar o cdigo do {&OUT} com o texto a ser mostrado.

SPEEDSCRIPT

Comentrios
Dentro da rea do SpeedScripts, possvel colocar comentrios. Seu uso idntico ao uso no
4GL, iniciando com /* e finalizando com */.
Blocos
Como no 4GL, para o SpeedScript o bloco uma seqncia de um ou mais linhas de
comandos, incluindo outros blocos. O funcionamento do bloco, incluindo o escopo de registros
e variveis so os mesmos do 4GL. A procedure externa o bloco mais bsico para o
SpeedScript, pois pode conter uma ou mais linhas de comandos e a menor unidade que pode
ser compilada separadamente. Objetos WEB so sempre procedures externas. Outra
caracterstica que a procedure externa o nico bloco que necessita de uma sintaxe especial
para ser executada, enquanto os demais blocos continuam usando sua prpria terminologia
para abrir os blocos e o comando END para encerr-los.
A diferena bsica est na maneira de construir um aplicativo no SpeedScript. A interao
entre o Progress e o HTML acontece com o uso de TAGS especficas. Ao abrir e fechar as
TAGS do SCRIPT, os blocos no necessitam ser abertos e fechados dentro de uma mesma
TAG SpeedScript. A abertura do bloco pode acontecer em um momento, separada por
informaes da montagem do HTML e depois as TAGS SpeedScript para encerrar o bloco.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>WebSpeed Script</TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="SpeedScript">

SPEEDSCRIPT

/*-----------------------------------------------------------------File:
Description:
Created:
-------------------------------------------------------------------*/
REPEAT WHILE TRUE: /* Inicia bloco de interao */
RUN maxCustomers.
END. /* finaliza bloco de interao */
PROCEDURE maxCustomer: /* Inicia bloco de procedure interna */
FOR EACH customer USE-INDEX NAME NO-LOCK: /* Inicia bloco de interao */
IF customer.balance > 30000 THEN DO: /* Inicia bloco */
{&DISPLAY} customer.NAME customer.balance.
END. /* Finaliza bloco */
END. /* Finaliza bloco de interao */
END PROCEDURE. /* Finaliza o bloco de procedure interna */
</SCRIPT>
</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo5/exemplo06.html

E o resultado final semelhante a uma listagem.

5.2.1. Executando Procedures e Objetos WEB


A execuo de procedures no SpeedScript feita pelo comando RUN, podendo ser usado de
diversas formas. O mais bsico a execuo da procedure diretamente, sendo uma procedure
interna ou externa. Lembrando ainda que, como no 4GL, as procedures internas so
identificadas pela palavra PROCEDURE na sua definio, enquanto a procedure externa

SPEEDSCRIPT

todo e qualquer tipo de conjunto de linhas de comandos. Ainda para as procedures, seja
interna ou externa, a passagem de parmetros a mesma aplicada no 4GL.
Procedures Persistentes
Quando uma procedure externa executada de modo persistente, permanece em memria
com todo seu contexto de variveis e procedures internas mesmo depois do cdigo principal
(MAIN BLOCK) ter sido executado e finalizado. Isto nos permite a facilidade de instanciar
objetos WEB, no caso SpeedScripts. Isto possvel porque na execuo da procedure, o
endereo (HANDLE) do mesmo pode ser armazenado em variveis, possibilitando seu acesso,
mesmo depois do fim do MAIN BLOCK da procedure externa. Com o HANDLE da procedure
executada persistentemente, possvel acessar suas procedures e funes internas. Mas para
isso necessrio utilizar a opo IN com a varivel que contm o endereo da procedure.
Procedures prprias do WebSpeed
O WebSpeed possui um conjunto de procedures chamadas Conventions. A primeira delas o
mtodo run-web-object, onde tem como finalidade executar um objeto WEB de uma outra
procedure. Outra procedure bsica a web-disp.p que executada por objetos WEB,
respondendo requisies WEB. O mtodo run-web-object segue um padro garantindo a
integridade do objeto WEB, seja STATELESS ou STATE-AWARE, permitindo ao WebSpeed
gerenciar os objetos WEB. Este mtodo encontrado no objeto instalaoprogress/src/web/objects/web-util.p.
A outra conveno sobre o disparo dos mtodos. Ao executar a procedure, diversos mtodos
podem ser sobrescritos, mas sem alterar o mtodo original. Assim a customizao feita
executada antes e/ou depois da execuo do mtodo original. Os mtodos esto definidos na
include instalao-progress/src/web/method/admweb.i.

5.2.2. Blocos e Contextos


O contexto ou escopo de um bloco est ativo sempre do incio ao fim do bloco. Os blocos
podem ser divididos basicamente em dois tipos: Explcitos e Implcitos. Os blocos explcitos
iniciam com comandos, como, por exemplo, o FOR EACH, REPEAT e DO seguidos de dois
pontos (:) e so finalizados com o comando END. Os blocos implcitos so as procedures
externas com todo seu contedo. O escopo da procedure externa para o SpeedScript contm
todos os dados, objetos, triggers, procedures internas e funes.
Uma trigger no SpeedScript um comando ou bloco que responde a um evento do
SpeedScript e descrito com o comando ON. Apesar de limitados, os eventos no SpeedScript
so importantes para o WebSpeed, sendo identificados pelos eventos chamados WEBNOTIFY, CLOSE e os diversos eventos do banco de dados.
Normalmente, qualquer dado ou objeto definido dentro do contexto de uma procedure, estar
disponvel apenas para os comandos desta procedure. Entretanto, estas definies de objetos
e dados em outros tipos de blocos so parte do contexto da procedure e no apenas do bloco
onde foram definidos.

5.2.3. Contexto do Bloco e Escopo


O contexto de alguns blocos ajuda a determinar o escopo de alguns recursos. Escopo a
durao de uma atividade na aplicao, estando dependente do tipo de comando utilizado e da
condio de execuo da aplicao. O escopo iniciado quando o recurso instanciado e
finalizado na sua destruio. Por exemplo, o comando FOR determina o escopo do buffer de

SPEEDSCRIPT

uma tabela. O escopo de cada registro lido idntico ao contexto do bloco FOR, pois o escopo
eliminado no fim do bloco.
Recursos Dinmicos
Tudo que dinmico significa que pode ser criado e eliminado em tempo de execuo, seja de
forma implcita ou explcita. Por exemplo, o buffer de um registro do comando FOR que foi
definido implicitamente so buffers dinmicos. O WebSpeed cria esses buffers quando o bloco
FOR executado e os elimina quando a execuo finalizada. O escopo de um frame no
SpeedScript para o bloco FOR funcionam da mesma maneira. Todo o contexto da procedure
dinmico. WebSpeed cria recursos de dados locais quando uma procedure executada e
elimina esses recursos quando feito o retorno da procedure executada, seno voltaria fora do
escopo. Entretanto, o WebSpeed permite criar e eliminar alguns recursos dinmicos
explicitamente. Para o WebSpeed, isto aplicado para o contexto de procedures externas
(procedures persistentes) dos objetos WEB.
Normalmente, o escopo do ltimo recurso dinmico do momento da criao at o momento de
sua eliminao, ou no fim da sesso do Agente do WebSpeed, independente de qual ocorrer
primeiro. Quando o bloco da procedure completado e seu contexto fica fora do escopo, isto
no afeta o escopo de qualquer recurso dinmico que tenha sido criado no contexto. Completar
as procedures pode somente afetar se o recurso ainda est acessvel no contexto
remanescente.
O WebSpeed permite definir gerenciamentos na maioria dos recursos dinmicos. Esses
gerenciadores so variveis que apontam para o recurso criado. necessrio assegurar que
os gerenciamentos desses recursos, esto sempre disponveis aplicao at o recurso ser
eliminado. Se o contexto for criado para uma procedure persistente e no for eliminado
explicitamente, o contexto permanece no escopo enquanto durar a sesso do Agente, no
importando possveis acessos feitos por um Client. Caso o endereo original do contexto da
procedure seja perdido, no ser mais possvel acess-lo novamente, ficando em memria
sem a possibilidade de ser eliminado explicitamente.

5.2.4. Tempo de Compilao X Tempo de Execuo


Cdigos do Tempo de Compilao
Alguns comandos existem apenas para gerar o RCODE no momento da compilao. Isto ,
dados e recursos de buffers so criados de forma esttica, para que na execuo possam ser
referenciados e modificados, mas no destrudos durante a execuo.
Elementos da Sintaxe no Tempo de Compilao
Comandos prprios compilao, incluindo comandos do SpeedScript que iniciam com
a palavra DEFINE.
Componentes no executveis de comandos dos cabealhos de blocos e os comandos
END.
Opes e frases associadas aos comandos de tempo de compilao.
Expresses de literais ou constantes.
Definies e diretivas de pr-compilao (Preprocessadores).
Cdigos do Tempo de Execuo
Os comandos de tempo de execuo usam os recursos estticos criados na compilao, mas
podem tambm criar, usar e eliminar dinamicamente recursos no prprio tempo de execuo.
Diversos comandos de tempo de execuo possuem opes no tempo de compilao.

SPEEDSCRIPT

Elementos da Sintaxe no Tempo de Execuo


As opes e frases associadas com comandos em tempo de execuo, incluindo
componentes executveis de comandos de cabealhos de blocos, exceto opes e
frases que tambm esto associadas com comandos de tempo de compilao.
Comandos de atualizao e expresses no literais (variveis, funes, atributos e
mtodos).
Interao entre Tempo de Compilao e de Execuo
Como o SpeedScript uma linguagem interpretada em tempo de execuo, possvel
combinar os dois tempos em diversos modos. Um exemplo bem simplista para esse caso, seria
a execuo pelo comando RUN de outro programa.

5.3. PREPROCESSADORES DO WEBSPEED


O preprocessador uma funo do 4GL que tambm aplicvel ao SpeedScript. O valor do
preprocessador uma constante e onde for usado, no momento da compilao ser
substitudo pelo valor que foi atribudo a ele. O uso do preprocessador no cdigo fonte entre
chaves e a palavra iniciada sempre com o caracter &.
O uso dos preprocessadores no WebSpeed facilita a utilizao para o ambiente WEB,
simplificando o desenvolvimento, especialmente, quando se deve referenciar a sada do
STREAM para WEB. Essas definies dos nomes dos preprocessadores esto localizadas em
instalao-progress/src/web/method/cgidefs.i.
Preprocessadores do WebSpeed
Nome do Preprocessador
&WEBSTREAM
&OUT
&OUT-FMT
&DISPLAY

Valor Atribudo ao Preprocessador


STREAM Webstream
PUT {&WEBSTREAM} UNFORMATTED
PUT {&WEBSTREAM}
DISPLAY {&WEBSTREAM}

5.4. APIS DO WEBSPEED


5.4.1. Gerenciamento de Mensagens
Existe um nmero de funes das APIs do WebSpeed para mensagens. Essas funes podem
ser localizadas em instalao-progress/src/web/method/message.i.
Funes de Mensagens das APIs
Funo
available-messages

Tipo Retorno
Descrio
Lgico
Retorna TRUE se existe qualquer mensagem na fila
para um grupo especfico ou para todos os grupos.
get-messages
Caracter
Retorna qualquer mensagem da fila para um grupo
especfico ou todos os grupos. Opcionalmente pode
eliminar uma mensagem da fila.
get-message-groups Caracter
Retorna a lista de mensagens da fila separadas por
vrgula.

SPEEDSCRIPT

output-messages

Inteiro

queue-message

Inteiro

Sada da mensagem para a WEB que estava na fila e


retorna o nmero da mensagem que saiu. Inclui opo
para formatar a sada e pode especificar um grupo de
mensagens ou todas as mensagens.
Enfileira a mensagem para posteriormente poder us-la
pelo mtodo output-messages e retorna o nmero da
mensagem na fila. Opcionalmente, associa a mensagem
com um grupo especfico.

Gerando as Mensagens Diretamente


Em SpeedScript, onde o cdigo do programa controla a sada do HTML, possvel chamar
uma funo de mensagem da API diretamente. Na maioria dos casos, necessrio somente o
uso do output-message e queue-message. Essas funes executam outras funes da API.

5.4.2. Passando Informaes entre Requisies WEB


Existem quatro meios de passar informaes entre requisies WEB:
Cookies
Query String na URL
Campos escondidos no FORM
Campos dos Usurios.
As trs primeiras tcnicas esto disponveis para todos os objetos WEB, STATELESS ou
STATE-AWARE. Entretanto, campos dos usurios esto disponveis apenas para uma simples
requisio ou uma transao do WebSpeed.
WebSpeed suporta todas as tcnicas com funes de APIs ou mtodos. Algumas funes so
especficas para uma tcnica e algumas combinam essas tcnicas para disponibilizar as
informaes para um objeto WEB.
Cookies
Os Cookies permitem passar informaes como parte do cabealho HTTP da pgina WEB e
uma das tcnicas mais usadas, pois pode identificar o usurio do WEB site. De fato, a
transao WebSpeed depende na forma de passagem do cookie pelo programa de controle do
agente de transao WebSpeed (web-disp.p) e o Broker.
Funes da API de passagens de parmetros por Cookie
Funo
delete-cookie
get-cookie

Tipo Retorno
Caracter
(Desconhecido ou ?)
Caracter

set-cookie

Caracter

Descrio
Elimina um Cookie especfico pelo seu nome, URL,
caminho e domnio na internet.
D um nome ao Cookie, retornando um ou mais valores
combinados, delimitados pelo valor da varivel global
WebSpeed SelDelim, separado por vrgula. Se o nome
do Cookie um valor desconhecido (?), retorna a lista
de todos os nomes de Cookies.
Retorna um cabealho Set-Cookie HTTP com opes
especficas e retorna o valor do Cookie especfico.

As definies dessas funes esto no instalao-progress/src/web/method/cookies.i.


Deve-se invocar as funes delete-cookie e set-cookie com o mtodo output-header do objeto
WEB. Nos objetos WEB do SpeedScript deve-se incluir a definio da procedure output-header

SPEEDSCRIPT

no comando de sada da TAG. Para gerao dos objetos WEB SpeedScript e HTML-Mapping,
o WebSpeed possui uma definio da procedure output-header padro que pode ser
modificada no editor do WebSpeed.
Query String na URL
Estes so usados para passar faixas de informaes, da requisio do CGI para valores
explcitos colocados nos links dinmicos. Existem diversas funes das APIs para facilitar a
construo e leitura das URLs.
Funes de APIs para URL
Funo
url-decode

Tipo Retorno
Descrio
Caracter
Decodifica o formato de entrada da URL de mtodos de
requisio GET e CGI POST ou valores de Cookies codificados e
retorna um texto decodificado.
url-encode Caracter
Codifica caracteres na URL por RFC 1738 sesso 2.2, disponvel
em:
URL:http://ds.internic.net/rfc/rfc1738.txt,
adicionando
caracteres ASCII entre 0 e 31 e entre 127 e 255. Opes podem
modificar a codificao para o Query Strings do endereo URL,
Cookies persistentes, ou um texto especfico de caracteres,
retornando o texto codificado.
url-field-list Caracter
Codifica uma lista de pares de Nomes/Valores de uma lista de
nomes cujos valores so recuperados de uma requisio corrente
de uma funo GET-VALUE. Parmetros incluem o nome da lista
e o delimitador. Retorna uma lista codificada de pares de
Nomes/Valores.
url-field
Caracter
Codifica pares de Nomes/Valores para usar como argumentos de
campos no URL. Parmetros incluem nomes, valores e
delimitadores para cada par. Retorna o par Nome/Valor
codificado.
url-format Caracter
Formata uma URL de uma URL base, lista de nomes e
delimitadores (A lista de nomes est codificada usando a url-fieldlist). Retorna a URL codificada.
As definies dessas funes esto em instalao-progress/src/web/method/cgiutils.i.
Para mais aplicaes, a funo url-format est na funo principal da API para construir URLs.
Esta funo chama as funes da tabela anterior. Para construir Query Strings na URL, devese tambm chamar a funo set-user-field para montar o par nome/valor para o Query Strings.
Para ler uma string de texto na URL, a funo mais comum e fcil para usar o get-value, que
pesquisa diversos fontes para o valor associado com o nome.
Query Strings da URL so limitados pela quantidade de informaes por URLs. Para uma
maior lista de dados que podem ser acumulados na aplicao, deve-se usar campos
escondidos.
Campos Escondidos no Form
Campos escondidos permitem passagens de parmetros praticamente inesgotvel nas
requisies WEB. Baseado na entrada de dados de um FORM possvel retornar valores de
campos como campos escondidos para uma prxima requisio WEB, isto mantm um registro
corrente de dados entre objetos WEB para objetos WEB e de Agentes para Agentes.
Funes para Campos Escondidos
Funo

Tipo Retorno

Descrio

SPEEDSCRIPT

hidden-field

Caracter

hidden-field-list Caracter

Retorna um texto contendo um campo escondido no form do


HTML com caracteres especiais do HTML codificados. Os
parmetros incluem o nome e valores dos campos.
Formata e retorna uma lista de campos escondidos
delimitados por uma nova linha de caracteres. Os parmetros
incluem uma lista de nome de campos recuperados de uma
requisio corrente

Essas funes podem ser visualizadas em instalao-progress/src/web/methodcgiutils.i.


Na maioria das aplicaes, hidden-field-list a principal funo para construir campos
escondidos, pois, pode-se definir um ou mais campos escondidos com ela. Para construir uma
lista de campos escondidos, a funo set-user-field usada para definir o par nome/valor para
cada campo escondido, chamando em seguida a funo hidden-field-list para construir os
campos escondidos da lista de campos do usurio.
Para leitura dos campos escondidos individualmente, deve-se usar a funo get-value.
Campos dos Usurios
WebSpeed possui uma lista global que permite os objetos WEB se comunicarem no mesmo
Agente. Esta a lista de campos dos usurios. Como uma estrutura de dados globais, muitos
objetos WEB so executados em uma nica requisio WEB ou em uma mesma transao do
WebSpeed, podendo passar informaes em campos de usurios, sem passar parmetros.
Funes de Campos de Usurios
Funo
get-user-field

set-user-field

Tipo Retorno
Descrio
Caracter
Retorna o valor associado de um campo de usurio especfico
que foi setado com a funo set-user-field. Se um nome de
campo de usurio definido como desconhecido (?), a lista
inteira de campos de usurios retornada.
Caracter
Seta os valores associados para um campo de usurio
especfico. Os parmetros incluem os nomes e valores dos
campos. Se o nmero de campos menor ou igual a 255, a
funo retorna TRUE, seno retorna FALSE.

Estas funes esto armazenadas em instalao-progress/src/web/method/cgiutils.i.


Campos de usurios so setados como Nome/Valor que mantm uma lista de variveis
WebSpeed globais do tipo caracter. Estes campos esto disponveis, sem necessitar de
declarao, para todos os objetos WEB executados no mesmo Agente para uma mesma
requisio WEB ou transao do WebSpeed (Se o Agente estiver preso). Caso no exista uma
transao do WebSpeed, os campos de usurios possuem um meio de passar dados entre
diversos objetos WEB por uma simples requisio.
A funo set-user-field tem uma larga aplicao no WebSpeed. Setar os pares de
nomes/valores para diversos dados passando por funes, incluindo url-format, url-field-list
(para Query Strings), hidden-field-list e get-value.

5.4.3. Troca Geral de Informao


WebSpeed suporta diversas funes para troca de informaes.
Funes para trocas de informaes

SPEEDSCRIPT

Funo
get-cgi

Tipo Retorno
Descrio
Caracter
Retorna o valor de uma varivel CGI especificada, ou retorna a
lista de todas as variveis CGI se o nome da varivel
especificada for um valor desconhecido (?). Retorna em branco
( ) se o nome invlido.
get-field
Caracter
Retorna um valor associado para um campo do form
especificado ou um Query Strings, ou retorna a lista de todos os
campos da form na requisio corrente se o nome do campo
especificado tem o valor desconhecido (?). Retorna branco ( ),
se o nome invlido.
get-value
Caracter
Retorno o primeiro valor disponvel associado com o nome de
um campo de usurio, um campo do form, um Query Strings ou
um cookie.Se o nome especificado tem o valor desconhecido (?),
retorna a lista de todos os campos do usurio e cookies. Retorna
branco ( ) se o nome invlido. Esta a funo mais usada.
html-encode Caracter
Converte vrios caracteres ASCII de uma string para uma
representao HTML. Retorna uma string HTML codificada. Esta
funo normalmente usada para construir uma sada HTML de
um programa SpeedScript. Entretanto, no se deve repetir a
execuo de uma string para evitar a corrupo de uma
codificao.
As definies dessas funes esto no instalao-progress/src/web/method/cgiutils.i.

5.4.4. Gerenciamento de Datas e Informao de Tempo


Funes de Data e Hora
Funo
Tipo Retorno
Descrio
convert-datetime Caracter
A entrada para converso uma data especificada com o
(Branco, )
tipo de DATE do SpeedScript e a hora especificada como
nmero de segundos deste a meia-noite (funo TIME). A
sada a data e hora convertida da hora local para UTC, de
UTC para hora local, ou normalizado para ter o nmero de
segundos em um dia.
format-datetime Caracter
Formata e retorna uma data e hora para uso na WEB.
Suporta formatos incluindo COOKIE e HTTP". O formato
COOKIE usado para setar data de expirao do cookie.
O formato HTTP" usado para datas em cabealhos HTTP.
As definies dessas funes esto no instalao-progress/src/web/method/cgiutils.i.

5.4.5. Gerando Cabealhos da Pgina WEB


Para a funo output-http-header ter qualquer efeito, deve-se executar antes a funo outputcontent-type.
Funes de Cabealhos para Pgina WEB
Funo
Tipo Retorno
output-content-type Lgico

Descrio
Seta e retorna o cabealho MIME Content-Type
seguido de uma linha em branco. Se o cabealho j
foi retornado, nenhuma ao tomada. Se o tipo do
contedo especificado branco, nenhum cabealho

SPEEDSCRIPT

output-http-header

Content-Type retornado, mas outros cabealhos,


como um Cookies, so retornados seguidos de uma
linha em branco. Retorna TRUE se o cabealho
Content-Type retornado, caso contrrio, retorna
FALSE.
Caracter
Retorna o cabealho de um HTTP especfico e
(Desconhecido, ?) associa um valor, seguido por um retorno de carro
(CR) e um linefeed (LF). Se o cabealho branco, o
CR e o LF ainda so retornados.

As definies dessas funes esto no instalao-progress/src/web/method/cgiutils.i.

5.4.6. Checando Opes de Configuraes


Existem funes que permitem alterar o comportamento da aplicao baseado no tipo do
ambiente onde o Agente do WebSpeed est sendo executando.
Funes de Configurao
Funo
check-agent-mode

get-config

Tipo Retorno
Descrio
Lgico
Retorna TRUE se o Agente do WebSpeed est sendo
executado em modo Development, Production ou
Evaluation. Caso contrrio, retorna FALSE.
Caracter
Retorna a configurao do valor especificado do
WebSpeed Transaction Server.

As definies dessas funes esto no instalao-progress/src/web/objects/web-util.p.

5.5. EMBEDDED SPEEDSCRIPT


Embedded SpeedScript constri objetos WEB diretamente de um padro de arquivos HTML,
incluindo SpeedScript como uma linguagem de script.
O arquivo Embedded SpeedScript como um arquivo esttico HTML, onde possvel
adicionar uma sesso SpeedScript usando comandos especficos.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Exemplo de SpeedScript</TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="SpeedScript">
/*-----------------------------------------------------------------File:
Description:
Created:
-------------------------------------------------------------------*/
FOR EACH customer WHERE customer.NAME BEGINS "S" NO-LOCK:
DISPLAY {&WEBSTREAM} customer EXCEPT customer.comments.
END.
</SCRIPT>
</BODY>

SPEEDSCRIPT

</HTML>
Exemplo localizado em: exemplo/capitulo5/exemplo07.html

O bloco FOR est dentro do Embedded SpeedScript, onde o Embedded SpeedScript


referenciado pela tag HTML <SCRIPT>. Diferentemente do JavaScript que executa
normalmente no client, SpeedScript executa o cdigo inteiramente no WebSpeed Transaction
Server. Com a execuo no lado do servidor, o Embedded SpeedScript pode referenciar
variveis e campos dos bancos de dados do objeto WEB de qualquer lugar do arquivo HTML.
Com o uso do Embedded SpeedScript, o AppBuilder converte o arquivo HTML para um objeto
WEB SpeedScript que gera a pgina WEB atual. Esta pgina WEB pode ser uma pgina
esttica simples ou uma pgina complexa e dinmica.
O Embedded SpeedScript pode gerar dois tipos de sadas para o WebSpeed:
Objetos WEB completos, prontos para executar, podendo gerenciar sada e entrada
para WEB.
SpeedScript possui arquivos que podem incluir no cdigo fonte do SpeedScript outro
objeto WEB para compilao futura.
Entretanto, o Progress no consegue compilar HTML. O SpeedScript possibilita um
desenvolvimento fcil em HTML, podendo-se usar ferramentas prprias para isso. Porm, na
compilao dos programas, o Progress converte o SpeedScript para CGI Wrapper, colocando
as TAGS entre aspas e tirando a TAG SCRIPT para que possa compilar o cdigo Progress.
Esse processo transparente para o desenvolvedor.

5.6. COMO COLOCAR SPEEDSCRIPT NO HTML


WebSpeed possui dois tipos bsicos de opes para colocar SpeedScript no arquivo HTML:
Comandos de escape.
Expresses de escape.
Comandos de escape permitem incluir um ou mais comandos SpeedScript completos no
HTML, enquanto expresses de escape permitem incluir expresses SpeedScript que tem
formatos caracter. possvel codificar cada tipo de escape usando diferentes conjuntos de
combinaes de TAGS iniciais e finais. A escolha das TAGS minimiza a chance da ferramenta
usada de no aceitar o escape.

5.6.1. Comandos de Escape


Comandos de escape no Embedded SpeedScript
Tag Inicial
Tag Final
<SCRIPT LANGUAGE = </SCRIPT>
SpeedScript>
<?WS>
</?WS>

<SERVER>
<%
<!--WSS

Comentrios
Suportado pela maioria das ferramentas.

So TAGS definidas para o WebSpeed. O sinal <?


uma diretiva SGML, porm, algumas ferramentas
podem no suportar as TAGS.
</SERVER> WebSpeed suporta essas TAGS, mas no permite
especificar uma linguagem.
%>
So tags do ASP (Microsoft Active Server Pages).
-->
Este escape uma TAG semelhante ao SCRIPT.
Entretanto, funciona apenas para uma nica linha.

SPEEDSCRIPT

Mas algumas ferramentas podem no suportar isso.


O comando escape pode fechar qualquer nmero de comandos SpeedScript completos. Outra
maneira de usar isso pelo <?WS> para abrir e </?WS> para fechar.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Exemplo de SpeedScript</TITLE>
</HEAD>
<BODY>
<?WS>
/*-----------------------------------------------------------------File:
Description:
Created:
-------------------------------------------------------------------*/
FOR EACH customer WHERE customer.NAME BEGINS "S" NO-LOCK:
DISPLAY {&WEBSTREAM} customer EXCEPT customer.comments.
END.
</?WS>
</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo5/exemplo08.html

5.6.2. Expresses de Escape


Expresses de Escape do Embedded SpeedScript
Tag Inicial Tag Final
Comentrios
`
`
A crase (`) aceita na maioria das ferramentas WEB.
{=
=}
Este escape mais fcil de marcar do que a crase (`) e tambm
aceita na maioria das ferramentas WEB.
<%=
%>
Esses so TAGS do ASP (Microsoft Active Server Pages) e pode ter
problemas em algumas ferramentas.
<!--WSE
-->
Este escape um comentrio HTML definido no WebSpeed e
suportado por praticamente todas as ferramentas. Este escape pode
ser til onde colocar o Embedded SpeedScript, mas pode ser
considerado como errado em algumas ferramentas.
Uma expresso de escape pode fechar qualquer seqncia de expresses de SpeedScript
vlido com uma sada no formato caracter, incluindo variveis, campos do banco de dados,
funes e strings. Ainda possvel colocar escape de expresso sozinha ou como parte de
uma string HTML.
No exemplo seguinte, cada expresso SpeedScript um campo de banco de dados colocado
em uma clula de tabela do HTML. Tudo que est entre crases no HTML no estar entre
aspas no programa fonte Progress. Mas importante colocar espaos em branco entre os
sinais de crase e o item usado.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Exemplo de SpeedScript</TITLE>
</HEAD>

SPEEDSCRIPT

<BODY>
<!--WSS FOR EACH customer
<TR>
<TD> `customer.custnum`
<TD> `customer.name`
<TD> `customer.phone`
</TR>
<!--WSS END. -->

WHERE customer.name BEGINS "S" NO-LOCK: -->


</TD>
</TD>
<BR></TD>

</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo5/exemplo09.html

5.7. CONSTRUO DE PGINAS WEB INTERAGINDO


COM EMBEDDED SPEEDSCRIPT
possvel usar Embedded SpeedScript para construir objetos WEB direcionados por
requisio ou chamados diretamente por outros objetos WEB. Objetos WEB Embedded
SpeedScript construdos podem usar todas as tcnicas disponveis para qualquer objeto WEB.
possvel construir quase todos os tipos de pginas WEB dinmicas com Embedded
SpeedScript que incluem forms to bem como tabelas.

5.7.1. Passando Parmetros


No exemplo a seguir mostrado como possvel acessar parmetros em tempo de execuo.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<SCRIPT LANGUAGE="SpeedScript">
DEFINE INPUT PARAMETER pFiltro AS CHARACTER NO-UNDO.
</SCRIPT>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Exemplo de Passagem de Parmetros</TITLE>
</HEAD>
<BODY>
<H1>Programa Executado pelo Programa Exemplo11.r</H1>
<CENTER>
<H2>Pesquisa Informada de `pFiltro` </H2>
<TABLE BORDER="2">
<SCRIPT LANGUAGE="SpeedScript">
/*-----------------------------------------------------------------File:
Description:
Created:
-------------------------------------------------------------------*/
FOR EACH customer WHERE customer.NAME BEGINS pFiltro NO-LOCK:
</SCRIPT>
<TR>
<TD> `customer.custnum` </TD>
<TD> `customer.name`
</TD>
<TD> `customer.phone`
<BR></TD>
</TR>
<SCRIPT LANGUAGE="SpeedScript">
END.

SPEEDSCRIPT

</SCRIPT>
</TABLE>
</CENTER>
</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo5/exemplo10.html

Entretanto, a execuo desse programa diretamente ir ocasionar um erro, pois necessrio


passar parmetros para o mesmo. O parmetro a ser passado deve ser feito executando o
comando RUN do programa Exemplo11.r.

Para executar esse programa, deve-se fazer:


<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="Treinamento WebSpeed">
<TITLE>Exemplo de Passagem de Parmetros</TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="SpeedScript">
/*-----------------------------------------------------------------File:
Description:
Created:
-------------------------------------------------------------------*/
RUN exemplo/capitulo5/exemplo10.r("John").
</SCRIPT>
</BODY>
</HTML>
Exemplo localizado em: exemplo/capitulo5/exemplo11.html

SPEEDSCRIPT

O resultado desse tratamento uma pgina WEB com os registros localizados.

5.7.2. Gerenciamento de Pginas Dinmicas com


Forms
O Embedded SpeedScript pode gerenciar requisies GET e POST para forms. O exemplo a
seguir usa o Report Template da lista de templates. O programa representado nas imagens a
seguir o exemplo/capitulo5/exemplo12.html e nenhuma alterao foi realizada da template
original.
Definindo Pr-Processadores e Variveis
O incio do programa feito pela definio dos Pr-Processadores e variveis que sero
usadas no decorrer do programa, alm de inicializao do valor de algumas variveis, de
acordo com o valor informado na pgina WEB.

SPEEDSCRIPT

Nesta parte do exemplo, definido o ambiente local do objeto WEB, como as definies dos
preprocessadores. As execues da funo GET-FIELD retornam a entrada do usurio para
cada requisio.
No caso da linha com a funo GET-FIELD(NoJumpForm:U), a sua execuo retorna o valor
da Query String da URL.
Esta primeira sesso SpeedScript termina testando o valor de JumpFor para determinar o
formato de sada da prxima requisio. Como o SpeedScript termina em um bloco DO,
necessrio outra seqncia com outro bloco SpeedScript para finalizao desse bloco DO.
Definindo Forms
Aps o SpeedScript, um form HTML permite ao usurio especificar um nome de Customer, ou
ento o padro em ordem alfabtica.

SPEEDSCRIPT

A palavra SelfURL uma varivel global WebSpeed que fica em instalaoprogress/src/web/method/cgidefs.i que contm o URL do objeto WEB, apontando para o
diretrio ROOT do server. A varivel WEB local {&amp;Filter-Field}-key, definida anteriormente,
especifica o filtro da QUERY do banco de dados. O preprocessador do Embedded SpeedScript
troca &amp por &, fazendo a referncia do preprocessador {&Filter-Field} aparecer no
cdigo fonte do objeto WEB. Para finalizar, a palavra jumpto-value o mais recente nome da
tabela de Customer especificada pelo usurio para iniciar a QUERY.
importante verificar que os preprocessadores usados na sesso HTML foram definidas no
SpeedScript anterior e so usados com a TAG de escape representada pela CRASE.
O FORM Jumpto inclui campos escondidos, inclusive repo-to com um valor diferente de zero
(0) para indicar que o FORM foi mostrado e o usurio o est submetendo para o retorno de
uma QUERY. Este bloco DO inicia com HTMLs definidos nos preprocessadores do
SpeedScript para iniciar uma tabela HTML centralizada que gerenciar a sada da QUERY em
10 itens (Result-Rows) por vez.
Alm do fechamento do bloco DO.
Gerenciamento de Blocos, Execues Condicionais e Tratamento de Registros na Query

SPEEDSCRIPT

Esta sesso SpeedScript inclui o cdigo atual para resolver, reposicionar e extrair os registros
da QUERY, baseados na entrada fornecida pelo usurio. Para simplificar a interao do
Embedded SpeedScript com o HTML, este cdigo do SpeedScript tambm inclui o HTML
necessrio para especificar cada registro na tabela do HTML para a query. A linha da tabela
mostrada pela referncia {&DISPLAY-FIELDS} localizada na parte mais de baixo do cdigo.
A parte do cdigo representada a seguir, mostra como interagir o cdigo do HTML e o cdigo
Embedded SpeedScript, concluindo a QUERY em um bloco DO:

SPEEDSCRIPT

Esta sesso inicia outro bloco DO que comea setando o contedo inicial da query String para
qualquer requisio para o painel de navegao, que ainda ir ser mostrada.
Construindo uma Query String e Encerrando a Pgina WEB
Para finalizar, o exemplo seguinte mostra a parte referente criao do painel de navegao e
o fim da pgina WEB:

SPEEDSCRIPT

Onde os eventos onMouseOver e onMouseOut so eventos JavaScripts.


O painel de navegao construdo de uma tabela HTML incluindo botes com imagens
(GIFs) associados com gatilho de retorno para esta pgina WEB. Cada gatilho contm a query
string que especifica como reconstruir e navegar a query mais recente. O bloco DO da query
descrito anteriormente interpretar essa informao. A cada boto acessado, o link
correspondente disparado buscando as novas informaes lidas no banco de dados.

5.8. DESENVOLVENDO OBJETOS WEB COM


EMBEDDED SPEEDSCRIPT
Independente da ferramenta utilizada para criar um arquivo Embedded SpeedScript, deve-se
usar sempre o AppBuilder para gerar o objeto WEB resultante ou arquivo de include. O
AppBuilder permite criar o arquivo Embedded SpeedScript e gerar o arquivo WebSpeed. Mas
possvel criar o Embeeded SpeedScript usando outra ferramenta e carregando depois no
AppBuilder.

SPEEDSCRIPT

5.8.1. Construindo Objetos WEB Embedded


SpeedScript
O AppBuilder uma opo para criar um novo objeto WEB carregando um arquivo HTML
existente. Se o arquivo HTML um arquivo Embedded SpeedScript (que contenha qualquer
tags de comando ou expresses), o AppBuilder ento o carrega para gerar uma include ou
uma procedure diretamente. Se o arquivo HTML no um arquivo Embedded SpeedScript,
mas um arquivo HTML padro, o AppBuilder cria um objeto WEB HTML-Mapping separado
para o arquivo HTML carregado.
Diferente do objeto WEB HTML-Mapping, o AppBuilder sempre compila e gera o RCode para
um objeto WEB Embedded SpeedScript. Isto ocorre porque todo HTML usado para gerar uma
pgina WEB est contido no objeto WEB. O arquivo Embedded SpeedScript mantm todo o
cdigo fonte para o objeto WEB gerado. Como possvel modificar o objeto WEB HTMLMapping separadamente do arquivo HTML usado, o AppBuilder deve salvar o fonte
SpeedScript para o objeto WEB HTML-Mapping como um ponto de incio para alteraes. Para
isto necessrio adicionar uma include criada do Embedded SpeedScript fonte para o objeto
WEB HTML-Mapping existente.

5.9. EXEMPLO COMPLETO DO EMBEDDED


SPEEDSCRIPT
O exemplo criar um catlogo que pesquisar os itens da tabela ITEM do banco Sports. Para
isso, um formulrio HTML ser criado para possibilitar a interface.
1 Criao do HTML bsico que ser usado como formulrio na pgina WEB.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta name="SQLWorks" content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->
<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
</script>
<!-- Search Form -->
<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>
<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">
<OPTION Value="ItemNum">Item</OPTION>
<OPTION Value="ItemName">Nome</OPTION>

SPEEDSCRIPT

<OPTION Value="CatDescription">Descritivo do Item</OPTION>


</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor" LENGTH="30">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum">Item</OPTION>
<OPTION VALUE="ItemName">Nome</OPTION>
</SELECT>
</TD>
<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>
<TH WIDTH="20%">Numero do Item</TH>
<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<TR>
<TD><B>*Numero do Item</B></TD>
<TD>*Nome do Item</TD>
<TD ALIGN="Right">Valor</TH>
<TD ALIGN="RIGHT">*Quantidade</TH>
</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>
*Descritivo do item deve ser colocado aqui
</TD>
</TR>
</TABLE>
<!-- End of Results List -->
</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13.html

Este HTML desenhar um formulrio Com opes de pesquisa e com as reas onde os dados
sero colocados aps a pesquisa.

SPEEDSCRIPT

2 necessrio definir as variveis que formam as clusulas e dados para montagem da


query. As variveis definidas so:

cTipoPesquisa: Esta varivel do tipo caracter, possibilita a escolha do campo

desejado para se fazer a pesquisa. O valor atribudo a essa varivel, lido de um


objeto WEB definido como um SELECT (COMBO-BOX) chamado SearchType. Os
valores definidos nas opes so: Item, Nome e Descritivo do Item.
cPesquisaPor: Esta varivel do tipo caracter, possui a entrada do valor a ser usado na
pesquisa da clusula. O valor atribudo a essa varivel, lido de um objeto WEB
definido como um TEXT (FILL-IN) chamado SearchFor. Este campo no possui um
valor fixo, podendo ser digitado para a qualquer valor.
cClassificado: Esta varivel do tipo caracter, possibilita a escolha do campo
desejado para se fazer a pesquisa. O valor atribudo a essa varivel, lido de um
objeto WEB definido como um SELECT (COMBO-BOX) chamado SortBy. Os valores
definidos nas opes so: Item e Nome.
cPesquisa: Esta varivel do tipo caracter serve para auxiliar no tratamento de anlise
do cdigo. O valor atribudo a essa varivel, lido de um objeto WEB definido como
SUBMIT (BUTTON) chamado SubmitSearch. O valor desse SUBMIT : Pesquisa.
iItem: Esta varivel do tipo inteiro serve para analisar se o tipo de entrada digitado
inteiro no caso de selecionado a opo Item no tipo de pesquisa (SearchType) a ser
feito. O valor de SearchFor atribudo a este campo atravs da funo INTEGER.
hQueryItem: Esta varivel do tipo HANDLE e representa o endereo da QUERY da
tabela ITEM usada para pesquisar os registros. Atravs desse HANDLE, possvel
criar, preparar e abrir a QUERY, alm de navegar nos registros.
cWhere: Esta varivel do tipo caracter recebe a estrutura da clusula WHERE
necessria de acordo com as escolhas para o tratamento de abertura da QUERY.
cSort: Esta varivel do tipo caracter recebe a condio de classificao da QUERY.
lPesquisa: Esta varivel do tipo lgica, analisa as condies de erros para
apresentsao de mensagens quando necessrio.

SPEEDSCRIPT

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">


<html>
<head>
<meta name="SQLWorks" content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->
<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
DEFINE VARIABLE cTipoPesquisa AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisaPor AS CHARACTER NO-UNDO.
DEFINE VARIABLE cClassificado AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisa
AS CHARACTER NO-UNDO.
DEFINE VARIABLE iItem
AS INTEGER
NO-UNDO.
DEFINE VARIABLE hQueryItem
AS HANDLE
NO-UNDO.
DEFINE VARIABLE cWhere
AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSort
AS CHARACTER NO-UNDO.
DEFINE VARIABLE lPesquisa
AS LOGICAL
NO-UNDO.
</script>
<!-- Search Form -->
<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>
<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">
<OPTION Value="ItemNum">Item</OPTION>
<OPTION Value="ItemName">Nome</OPTION>
<OPTION Value="CatDescription">Descritivo do Item</OPTION>
</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor" LENGTH="30">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum">Item</OPTION>
<OPTION VALUE="ItemName">Nome</OPTION>
</SELECT>
</TD>
<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>

SPEEDSCRIPT

<TH WIDTH="20%">Numero do Item</TH>


<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<TR>
<TD><B>*Numero do Item</B></TD>
<TD>*Nome do Item</TD>
<TD ALIGN="Right">Valor</TH>
<TD ALIGN="RIGHT">*Quantidade</TH>
</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>
*Descritivo do item deve ser colocado aqui
</TD>
</TR>
</TABLE>
<!-- End of Results List -->
</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13-01.html

3 Adicionados comandos ASSIGN para atualizar os valores de campos do HTML. Estas


atualizaes so responsveis pela identificao dos valores informados nos campos que
possam ter sido alterados antes de selecionar o boto Pesquisa.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta name="SQLWorks" content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->
<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
DEFINE VARIABLE cTipoPesquisa AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisaPor AS CHARACTER NO-UNDO.
DEFINE VARIABLE cClassificado AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisa
AS CHARACTER NO-UNDO.
DEFINE VARIABLE iItem
AS INTEGER
NO-UNDO.
DEFINE VARIABLE hQueryItem
AS HANDLE
NO-UNDO.
DEFINE VARIABLE cWhere
AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSort
AS CHARACTER NO-UNDO.
DEFINE VARIABLE lPesquisa
AS LOGICAL
NO-UNDO.
/*
Atualizao das variveis para armazenar os campos de entrada do
formulrio. A funo GET-VALUE busca os valores dos campos no
formulrio ou que podem ter sido armazenados para um cookie em
uma primeira execuo.
*/
ASSIGN cTipoPesquisa = GET-VALUE("SearchType")
cPesquisaPor = GET-VALUE("SearchFor")
cClassificado = GET-VALUE("SortBy")
cPesquisa
= GET-VALUE("SubmitSearch").
</script>

SPEEDSCRIPT

<!-- Search Form -->


<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>
<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">
<OPTION Value="ItemNum">Item</OPTION>
<OPTION Value="ItemName">Nome</OPTION>
<OPTION Value="CatDescription">Descritivo do Item</OPTION>
</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor" LENGTH="30">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum">Item</OPTION>
<OPTION VALUE="ItemName">Nome</OPTION>
</SELECT>
</TD>
<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>
<TH WIDTH="20%">Numero do Item</TH>
<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<TR>
<TD><B>*Numero do Item</B></TD>
<TD>*Nome do Item</TD>
<TD ALIGN="Right">Valor</TH>
<TD ALIGN="RIGHT">*Quantidade</TH>
</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>
*Descritivo do item deve ser colocado aqui
</TD>
</TR>
</TABLE>
<!-- End of Results List -->
</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13-02.html

Para verificar os valores das variveis atualizadas, possvel colocar no final do programa,
antes da tag </body> a impresso do contedo dessas variveis. Isso auxiliar a analisar os
valores indicados.

SPEEDSCRIPT

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">


<html>
.
.
.
cTipoPesquisa
cPesquisaPor
cClassificado
cPesquisa

`
`
`
`

cTipoPesquisa `
cPesquisaPor `
cClassificado `
cPesquisa `

<br>
<br>
<br>
<br>

</body>
</html>

4 Atribuindo valores dinamicamente nos campos do HTML com os ltimos valores


submetidos pelo usurio. Isto feito dinamicamente setando o valor de entrada dos campos,
ou os outros tipos de objetos.
No prximo cdigo mostrada como setar dinamicamente os valores dos campos de uma
pgina com valores atribudos aos campos. Neste caso foi usado o sinal de crase para
identificar o caracter de escape. Ainda neste caso, as opes selecionadas para a pesquisa e
classificao podem ser lidas do HTML.
Desta forma, a cada SUBMIT ocasionado pelo boto Pesquisa, as informaes da atual
pesquisa ficam mantidas no HTML para possibilitar identificar quais foram os valores para as
informaes apresentada.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta name="SQLWorks " content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->
<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
DEFINE VARIABLE cTipoPesquisa AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisaPor AS CHARACTER NO-UNDO.
DEFINE VARIABLE cClassificado AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisa
AS CHARACTER NO-UNDO.
DEFINE VARIABLE iItem
AS INTEGER
NO-UNDO.
DEFINE VARIABLE hQueryItem
AS HANDLE
NO-UNDO.
DEFINE VARIABLE cWhere
AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSort
AS CHARACTER NO-UNDO.
DEFINE VARIABLE lPesquisa
AS LOGICAL
NO-UNDO.
/*
Atualizao das variveis para armazenar os campos de entrada do
formulrio. A funo GET-VALUE busca os valores dos campos no
formulrio ou que podem ter sido armazenados para um cookie em
uma primeira execuo.
*/
ASSIGN cTipoPesquisa = GET-VALUE("SearchType")
cPesquisaPor = GET-VALUE("SearchFor")
cClassificado = GET-VALUE("SortBy")

SPEEDSCRIPT

cPesquisa
</script>

= GET-VALUE("SubmitSearch").

<!-- Search Form -->


<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>
<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">
<OPTION Value="ItemNum" `
IF cTipoPesquisa = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION Value="ItemName" `
IF cTipoPesquisa = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
<OPTION Value="CatDescription" ` IF cTipoPesquisa = "CatDescription"
THEN "SELECTED" ELSE "" `>Descritivo do Item</OPTION>
</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor"
LENGTH="30" VALUE="` cPesquisaPor `">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum" ` IF cClassificado = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION VALUE="ItemName" ` IF cClassificado = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
</SELECT>
</TD>
<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>
<TH WIDTH="20%">Numero do Item</TH>
<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<TR>
<TD><B>*Numero do Item</B></TD>
<TD>*Nome do Item</TD>
<TD ALIGN="Right">Valor</TH>
<TD ALIGN="RIGHT">*Quantidade</TH>
</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>
*Descritivo do item deve ser colocado aqui
</TD>
</TR>
</TABLE>
<!-- End of Results List -->

SPEEDSCRIPT

cTipoPesquisa
cPesquisaPor
cClassificado
cPesquisa

`
`
`
`

cTipoPesquisa `
cPesquisaPor `
cClassificado `
cPesquisa `

<br>
<br>
<br>
<br>

</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13-03.html

5 Com a possibilidade de identificar os valores dinamicamente nos campos do HTML,


utilizado do recurso de query dinmica para leitura dos registros, utilizando os campos de
classificao e de pesquisa para montar a clusula. Para isso, ser usado o comando CASE
para popular as variveis com a clusula WHERE e de SORT. Isto pode ser visualizado com as
apresentaes dos contedos das variveis em tela. Desta forma possvel analisar como
ficaro as clusulas para abertura da QUERY.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta name="SQLWorks " content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->
<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
DEFINE VARIABLE cTipoPesquisa AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisaPor AS CHARACTER NO-UNDO.
DEFINE VARIABLE cClassificado AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisa
AS CHARACTER NO-UNDO.
DEFINE VARIABLE iItem
AS INTEGER
NO-UNDO.
DEFINE VARIABLE hQueryItem
AS HANDLE
NO-UNDO.
DEFINE VARIABLE cWhere
AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSort
AS CHARACTER NO-UNDO.
DEFINE VARIABLE lPesquisa
AS LOGICAL
NO-UNDO.
/*
Atualizao das variveis para armazenar os campos de entrada do
formulrio. A funo GET-VALUE busca os valores dos campos no
formulrio ou que podem ter sido armazenados para um cookie em
uma primeira execuo.
*/
ASSIGN cTipoPesquisa = GET-VALUE("SearchType")
cPesquisaPor = GET-VALUE("SearchFor")
cClassificado = GET-VALUE("SortBy")
cPesquisa
= GET-VALUE("SubmitSearch").
CASE cClassificado:
WHEN "ItemNum" THEN
ASSIGN cSort = " BY Item.Itemnum".
WHEN "ItemName" THEN
ASSIGN cSort = " BY Item.ItemName".
OTHERWISE DO:
END.
END CASE. /* Classificao */
CASE cTipoPesquisa:

SPEEDSCRIPT

WHEN "ItemNum" THEN


ASSIGN cWhere = "WHERE ItemNum = " + cPesquisaPor.
WHEN "ItemName" THEN
ASSIGN cWhere = "WHERE ItemName CONTAINS '" + cPesquisaPor + "'".
WHEN "CatDescription" THEN
ASSIGN cWhere = "WHERE CatDescription CONTAINS '" +
cPesquisaPor + "'".
OTHERWISE DO:
END.
END CASE. /* cTipoPesquisa */
</script>
<!-- Search Form -->
<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>
<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">
<OPTION Value="ItemNum" `
IF cTipoPesquisa = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION Value="ItemName" `
IF cTipoPesquisa = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
<OPTION Value="CatDescription" ` IF cTipoPesquisa = "CatDescription"
THEN "SELECTED" ELSE "" `>Descritivo do Item</OPTION>
</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor"
LENGTH="30" VALUE="` cPesquisaPor `">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum" ` IF cClassificado = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION VALUE="ItemName" ` IF cClassificado = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
</SELECT>
</TD>
<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>
<TH WIDTH="20%">Numero do Item</TH>
<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<TR>
<TD><B>*Numero do Item</B></TD>
<TD>*Nome do Item</TD>
<TD ALIGN="Right">Valor</TH>

SPEEDSCRIPT

<TD ALIGN="RIGHT">*Quantidade</TH>
</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>
*Descritivo do item deve ser colocado aqui
</TD>
</TR>
</TABLE>
<!-- End of Results List -->
cTipoPesquisa
cPesquisaPor
cClassificado
cPesquisa
cWhere
cSort

`
`
`
`
`
`

cTipoPesquisa `
cPesquisaPor `
cClassificado `
cPesquisa `
cWhere `
cSort `

<br>
<br>
<br>
<br>
<br>
<br>

</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13-04.html

6 Adicionando a query dinmica de item para o HTML. Para este item, ser adicionada uma
linha com a criao da query usando a varivel HANDLE hQueryItem j definida.
Aps os comandos CASES adicionados para especificar a clusula WHERE e SORT, deve ser
adicionado a lgica para setar o BUFFER da query e preparar a mesma para ser aberta,
obedecendo as variveis cWhere e cSort.
Neste tpico, ainda deve ser adicionado um novo bloco SpeedScript para comandar a abertura
da query. Isto deve ser feito antes do cdigo HTML mostrar os registros.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta name="SQLWorks " content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->
<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
DEFINE VARIABLE cTipoPesquisa AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisaPor AS CHARACTER NO-UNDO.
DEFINE VARIABLE cClassificado AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisa
AS CHARACTER NO-UNDO.
DEFINE VARIABLE iItem
AS INTEGER
NO-UNDO.
DEFINE VARIABLE hQueryItem
AS HANDLE
NO-UNDO.
DEFINE VARIABLE cWhere
AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSort
AS CHARACTER NO-UNDO.
DEFINE VARIABLE lPesquisa
AS LOGICAL
NO-UNDO.
CREATE QUERY hQueryItem.
/*
Atualizao das variveis para armazenar os campos de entrada do
formulrio. A funo GET-VALUE busca os valores dos campos no
formulrio ou que podem ter sido armazenados para um cookie em

SPEEDSCRIPT

uma primeira execuo.


*/
ASSIGN cTipoPesquisa = GET-VALUE("SearchType")
cPesquisaPor = GET-VALUE("SearchFor")
cClassificado = GET-VALUE("SortBy")
cPesquisa
= GET-VALUE("SubmitSearch").
CASE cClassificado:
WHEN "ItemNum" THEN
ASSIGN cSort = " BY Item.ItemNum".
WHEN "ItemName" THEN
ASSIGN cSort = " BY Item.ItemName".
OTHERWISE DO:
END.
END CASE. /* Classificao */
CASE cTipoPesquisa:
WHEN "ItemNum" THEN
ASSIGN cWhere = "WHERE ItemNum = " + cPesquisaPor.
WHEN "ItemName" THEN
ASSIGN cWhere = "WHERE ItemName CONTAINS '" + cPesquisaPor + "'".
WHEN "CatDescription" THEN
ASSIGN cWhere = "WHERE CatDescription CONTAINS '" +
cPesquisaPor + "'".
OTHERWISE DO:
END.
END CASE. /* cTipoPesquisa */
hQueryItem:SET-BUFFERS(BUFFER Item:Handle).
hQueryItem:QUERY-PREPARE("PRESELECT EACH ITEM " + cWhere + cSort).
</script>
<!-- Search Form -->
<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>
<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">
<OPTION Value="ItemNum" `
IF cTipoPesquisa = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION Value="ItemName" `
IF cTipoPesquisa = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
<OPTION Value="CatDescription" ` IF cTipoPesquisa = "CatDescription"
THEN "SELECTED" ELSE "" `>Descritivo do Item</OPTION>
</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor"
LENGTH="30" VALUE="` cPesquisaPor `">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum" ` IF cClassificado = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION VALUE="ItemName" ` IF cClassificado = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
</SELECT>
</TD>

SPEEDSCRIPT

<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<script language="SpeedScript">
hQueryItem:QUERY-OPEN.
</script>
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>
<TH WIDTH="20%">Numero do Item</TH>
<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<TR>
<TD><B>*Numero do Item</B></TD>
<TD>*Nome do Item</TD>
<TD ALIGN="Right">Valor</TD>
<TD ALIGN="RIGHT">*Quantidade</TD>
</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>
*Descritivo do item deve ser colocado aqui
</TD>
</TR>
</TABLE>
<!-- End of Results List -->
cTipoPesquisa
cPesquisaPor
cClassificado
cPesquisa
cWhere
cSort

`
`
`
`
`
`

cTipoPesquisa `
cPesquisaPor `
cClassificado `
cPesquisa `
cWhere `
cSort `

<br>
<br>
<br>
<br>
<br>
<br>

</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13-05.html

7 Criar um processo de repetio para mostrar todos os registros lidos pela query e adicionar
propriedades dinamicamente do item. Para essa repetio sero necessrios dois novos blocos
SpeedScript. O primeiro iniciando o bloco e o segundo fechando o mesmo.
Para concluir esse passo, substituir os textos que esto representando os campos pelos
prprios campos da tabela item usando o escape crase. Esta lgica deve ser adicionada aps
a abertura da QUERY.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta name="SQLWorks " content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->

SPEEDSCRIPT

<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
DEFINE VARIABLE cTipoPesquisa AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisaPor AS CHARACTER NO-UNDO.
DEFINE VARIABLE cClassificado AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisa
AS CHARACTER NO-UNDO.
DEFINE VARIABLE iItem
AS INTEGER
NO-UNDO.
DEFINE VARIABLE hQueryItem
AS HANDLE
NO-UNDO.
DEFINE VARIABLE cWhere
AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSort
AS CHARACTER NO-UNDO.
DEFINE VARIABLE lPesquisa
AS LOGICAL
NO-UNDO.
CREATE QUERY hQueryItem.
/*
Atualizao das variveis para armazenar os campos de entrada do
formulrio. A funo GET-VALUE busca os valores dos campos no
formulrio ou que podem ter sido armazenados para um cookie em
uma primeira execuo.
*/
ASSIGN cTipoPesquisa = GET-VALUE("SearchType")
cPesquisaPor = GET-VALUE("SearchFor")
cClassificado = GET-VALUE("SortBy")
cPesquisa
= GET-VALUE("SubmitSearch").
CASE cClassificado:
WHEN "ItemNum" THEN
ASSIGN cSort = " BY Item.ItemNum".
WHEN "ItemName" THEN
ASSIGN cSort = " BY Item.ItemName".
OTHERWISE DO:
END.
END CASE. /* Classificao */
CASE cTipoPesquisa:
WHEN "ItemNum" THEN
ASSIGN cWhere = "WHERE Itemnum = " + cPesquisaPor.
WHEN "ItemName" THEN
ASSIGN cWhere = "WHERE ItemName CONTAINS '" + cPesquisaPor + "'".
WHEN "CatDescription" THEN
ASSIGN cWhere = "WHERE CatDescription CONTAINS '" +
cPesquisaPor + "'".
OTHERWISE DO:
END.
END CASE. /* cTipoPesquisa */
hQueryItem:SET-BUFFERS(BUFFER Item:Handle).
hQueryItem:QUERY-PREPARE("PRESELECT EACH ITEM " + cWhere + cSort).
</script>
<!-- Search Form -->
<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>
<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">

SPEEDSCRIPT

<OPTION Value="ItemNum" ` IF cTipoPesquisa = "ItemNum"


THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION Value="ItemName" ` IF cTipoPesquisa = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
<OPTION Value="CatDescription" ` IF cTipoPesquisa = "CatDescription"
THEN "SELECTED" ELSE "" `>Descritivo do Item</OPTION>
</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor"
LENGTH="30" VALUE="` cPesquisaPor `">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum" ` IF cClassificado = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION VALUE="ItemName" ` IF cClassificado = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
</SELECT>
</TD>
<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<script language="SpeedScript">
hQueryItem:QUERY-OPEN.
</script>
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>
<TH WIDTH="20%">Numero do Item</TH>
<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<script language="SpeedScript">
REPEAT:
hQueryItem:GET-NEXT.
IF (hQueryItem:QUERY-OFF-END) THEN LEAVE.
</script>
<TR>
<TD><B>` Item.ItemNum `</B></TD>
<TD>` Item.ItemName `</TD>
<TD ALIGN="Right">` Item.Price `</TD>
<TD ALIGN="RIGHT">` Item.OnHand `</TD>
</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>
` Item.CatDescription `
</TD>
</TR>
<script language="SpeedScript">
END. /* REPEAT */
</script>
</TABLE>
<!-- End of Results List -->

SPEEDSCRIPT

cTipoPesquisa
cPesquisaPor
cClassificado
cPesquisa
cWhere
cSort

`
`
`
`
`
`

cTipoPesquisa `
cPesquisaPor `
cClassificado `
cPesquisa `
cWhere `
cSort `

<br>
<br>
<br>
<br>
<br>
<br>

</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13-06.html

8 importante adicionar verificaes para garantir que a entrada de dados feita pelo usurio
no possua erros para criar as clusulas de pesquisa. Existem basicamente 3 tipos de
verificaes que sero feitas nesse exemplo:
Se a QUERY possue dados aps sua abertura(Cdigo colocado aps a abertura da
query).
Se o campo Pesquisado Por possui um valor diferente de nulo.
Se a pesquisa for feita pelo nmero do item, este deve ser numrico.
O mtodo que trata mensagens deve ser usado para retornar mensagens de erro e avisos para
os eventos acima relacionados. Em caso de erro, uma varivel lgica dever ser atualizada
para determinar qual a sada deve ser mostrada.
Existe ainda uma lgica verificando o atributo NUM-RESULTS igual a ZERO (0) para o
evento de POST. Isto evitar que o programa inicia pesquisando todos os registros, pois como
a condio da QUERY ainda no foi criada, todos os registros sero lidos, podendo causar
lentido, dependendo da quantidade de registros no Banco de Dados. Como na primeira
execuo do programa um evento GET, a condio tambm no aceita, evitando a leitura
desnecessria de registros.
As mensagens foram criadas atravs dos mtodos QUEUE-MESSAGES, AVAILABLEMESSAGES e GET-MESSAGES.
No final do HTML deve existir outro bloco SpeedScript para finalizar os blocos de validaes
abertos.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta name="SQLWorks " content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->
<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
DEFINE VARIABLE cTipoPesquisa AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisaPor AS CHARACTER NO-UNDO.
DEFINE VARIABLE cClassificado AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisa
AS CHARACTER NO-UNDO.
DEFINE VARIABLE iItem
AS INTEGER
NO-UNDO.
DEFINE VARIABLE hQueryItem
AS HANDLE
NO-UNDO.
DEFINE VARIABLE cWhere
AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSort
AS CHARACTER NO-UNDO.
DEFINE VARIABLE lPesquisa
AS LOGICAL
NO-UNDO.

SPEEDSCRIPT

CREATE QUERY hQueryItem.


/*
Atualizao das variveis para armazenar os campos de entrada do
formulrio. A funo GET-VALUE busca os valores dos campos no
formulrio ou que podem ter sido armazenados para um cookie em
uma primeira execuo.
*/
ASSIGN cTipoPesquisa = GET-VALUE("SearchType")
cPesquisaPor = GET-VALUE("SearchFor")
cClassificado = GET-VALUE("SortBy")
cPesquisa
= GET-VALUE("SubmitSearch").
CASE cClassificado:
WHEN "ItemNum" THEN
ASSIGN cSort = " BY Item.ItemNum".
WHEN "ItemName" THEN
ASSIGN cSort = " BY Item.ItemName".
OTHERWISE DO:
ASSIGN lPesquisa = FALSE.
END.
END CASE. /* Classificao */
IF cPesquisaPor > "" THEN DO:
ASSIGN lPesquisa = TRUE.
CASE cTipoPesquisa:
WHEN "ItemNum" THEN DO:
ASSIGN iItem = INTEGER(cPesquisaPor) NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
ASSIGN lPesquisa = FALSE.
queue-message("ItemSearch","Valor do campo deve ser inteiro.<br>").
END.
ELSE
ASSIGN cWhere = "WHERE ItemNum = " + cPesquisaPor.
END.
WHEN "ItemName" THEN
ASSIGN cWhere = "WHERE ItemName CONTAINS '" + cPesquisaPor + "'".
WHEN "CatDescription" THEN
ASSIGN cWhere = "WHERE CatDescription CONTAINS '" +
cPesquisaPor + "'".
OTHERWISE DO:
ASSIGN lPesquisa = FALSE.
queue-message("ItemSearch", "Critrio para pesquisa incorreto.").
END.
END CASE. /* cTipoPesquisa */
END.
ELSE DO:
IF REQUEST_METHOD = "POST" THEN DO:
queue-message("ItemSearch","Entre com valor correto no campo para
pesquisa.<br>").
END.
END.
hQueryItem:SET-BUFFERS(BUFFER Item:Handle).
hQueryItem:QUERY-PREPARE("PRESELECT EACH ITEM " + cWhere + cSort).
</script>
<!-- Search Form -->
<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>

SPEEDSCRIPT

<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">
<OPTION Value="ItemNum" ` IF cTipoPesquisa = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION Value="ItemName" ` IF cTipoPesquisa = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
<OPTION Value="CatDescription" ` IF cTipoPesquisa = "CatDescription"
THEN "SELECTED" ELSE "" `>Descritivo do Item</OPTION>
</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor"
LENGTH="30" VALUE="` cPesquisaPor `">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum" ` IF cClassificado = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION VALUE="ItemName" ` IF cClassificado = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
</SELECT>
</TD>
<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<script language="SpeedScript">
IF lPesquisa THEN DO:
hQueryItem:QUERY-OPEN.
IF hQueryItem:NUM-RESULTS = 0 AND REQUEST_METHOD = "POST" THEN
queue-message("Pesquisa","No existe dados para essa pesquisa.<br>").
/* Mostrar resultado se existir */
IF hQueryItem:NUM-RESULTS > 0 THEN DO:
</script>
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>
<TH WIDTH="20%">Numero do Item</TH>
<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<script language="SpeedScript">
REPEAT:
hQueryItem:GET-NEXT.
IF (hQueryItem:QUERY-OFF-END) THEN LEAVE.
</script>
<TR>
<TD><B>` Item.ItemNum `</B></TD>
<TD>` Item.ItemName `</TD>
<TD ALIGN="Right">` Item.Price `</TD>
<TD ALIGN="RIGHT">` Item.OnHand `</TD>
</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>

SPEEDSCRIPT

` Item.CatDescription `
</TD>
</TR>
<script language="SpeedScript">
END. /* REPEAT */
</script>
</TABLE>
<!-- End of Results List -->
<script language="SpeedScript">
END. /* If hQueryItem:Num-Results > 0 */
END. /* IF lPesquisa */
IF available-messages("ItemSearch") THEN DO:
{&OUT} '<CENTER><B><FONT COLOR="RED">' get-messages("ItemSearch", TRUE)
'</FONT></B></CENTER>'.
END. /* if available-messages */
</script>
cTipoPesquisa
cPesquisaPor
cClassificado
cPesquisa
cWhere
cSort

`
`
`
`
`
`

cTipoPesquisa `
cPesquisaPor `
cClassificado `
cPesquisa `
cWhere `
cSort `

<br>
<br>
<br>
<br>
<br>
<br>

</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13-07.html

9 Uma procedure interna ser criada para setar cookies. Esses cookies armazenaram os
valores dos campos do HTML. Para isso um bloco de SpeedScript deve ser criado no incio do
HTML, antes da tag de BODY. Esses cookies iro manter salvas as ltimas entradas nos
campos de pesquisa e classificao.
Para que a QUERY no seja aberta na reexecuo do browser, deve ser feito o tratamento da
requisio. Assim, ao reexecutar o browser, apenas os campos aparecem com valores, mas
para abrir a query, necessrio clicar no boto de pesquisa.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta name="SQLWorks" content="Treinamento WebSpeed">
<title>Itens Existentes</title>
</head>
<!-- Insert code for the ouput-headers sub-procedure here */ -->
<script language="SpeedScript">
PROCEDURE output-headers:
set-cookie("SearchType", GET-VALUE("SearchType"), TODAY + 365,?,?,?,?).
set-cookie("SearchFor", GET-VALUE("SearchFor"), TODAY + 365,?,?,?,?).
set-cookie("SortBy", GET-VALUE("SortBy"), TODAY + 365,?,?,?,?).
END PROCEDURE.
</script>
<body>
<script language="SpeedScript">
/*-----------------------------------------------------------------Arquivo: item.htm
Descritivo: Pesquisar os registros da tabela Item
-------------------------------------------------------------------*/
DEFINE VARIABLE cTipoPesquisa AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPesquisaPor AS CHARACTER NO-UNDO.
DEFINE VARIABLE cClassificado AS CHARACTER NO-UNDO.

SPEEDSCRIPT

DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE

VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE

cPesquisa
iItem
hQueryItem
hBufferItem
cWhere
cSort
lPesquisa

AS
AS
AS
AS
AS
AS
AS

CHARACTER
INTEGER
HANDLE
HANDLE
CHARACTER
CHARACTER
LOGICAL

NO-UNDO.
NO-UNDO.
NO-UNDO.
NO-UNDO.
NO-UNDO.
NO-UNDO.
NO-UNDO.

CREATE QUERY hQueryItem.


/*
Atualizao das variveis para armazenar os campos de entrada do
formulrio. A funo GET-VALUE busca os valores dos campos no
formulrio ou que podem ter sido armazenados para um cookie em
uma primeira execuo.
*/
ASSIGN cTipoPesquisa = GET-VALUE("SearchType")
cPesquisaPor = GET-VALUE("SearchFor")
cClassificado = GET-VALUE("SortBy")
cPesquisa
= GET-VALUE("SubmitSearch").
CASE cClassificado:
WHEN "ItemNum" THEN
ASSIGN cSort = " BY Item.ItemNum".
WHEN "ItemName" THEN
ASSIGN cSort = " BY Item.ItemName".
OTHERWISE DO:
ASSIGN lPesquisa = FALSE.
END.
END CASE. /* Classificao */
IF cPesquisaPor > "" THEN DO:
ASSIGN lPesquisa = TRUE.
CASE cTipoPesquisa:
WHEN "ItemNum" THEN DO:
ASSIGN iItem = INTEGER(cPesquisaPor) NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
ASSIGN lPesquisa = FALSE.
queue-message("ItemSearch","Valor do campo deve ser inteiro.<br>").
END.
ELSE
ASSIGN cWhere = "WHERE ItemNm = " + cPesquisaPor.
END.
WHEN "ItemName" THEN
ASSIGN cWhere = "WHERE ItemName CONTAINS '" + cPesquisaPor + "'".
WHEN "CatDescription" THEN
ASSIGN cWhere = "WHERE CatDescription CONTAINS '" +
cPesquisaPor + "'".
OTHERWISE DO:
ASSIGN lPesquisa = FALSE.
queue-message("ItemSearch", "Critrio para pesquisa incorreto.").
END.
END CASE. /* cTipoPesquisa */
END.
ELSE DO:
IF REQUEST_METHOD = "POST" THEN DO:
queue-message("ItemSearch","Entre com valor correto no campo para
pesquisa.<br>").
END.
END.
hQueryItem:SET-BUFFERS(BUFFER Item:Handle).
hQueryItem:QUERY-PREPARE("PRESELECT EACH ITEM " + cWhere + cSort).
</script>

SPEEDSCRIPT

<!-- Search Form -->


<FORM NAME="PesquisaItem" METHOD="Post">
<TABLE ALIGN="Center" BORDER="1">
<TR ALIGN="CENTER">
<TD COLSPAN="8">Pesquisa de Itens</TD>
</TR>
<TR>
<TD>Tipo de Pesquisa</TD>
<TD>
<SELECT NAME="SearchType">
<OPTION Value="ItemNum">Item</OPTION>
<OPTION Value="ItemName">Nome</OPTION>
<OPTION Value="CatDescription">Descritivo do Item</OPTION>
</SELECT>
</TD>
<TD>Pesquisado por</TD>
<TD>
<INPUT TYPE="TEXT" Name="SearchFor"
LENGTH="30" VALUE="` cPesquisaPor `">
</TD>
<TD>Classificado por</TD>
<TD>
<SELECT NAME="SortBy">
<OPTION VALUE="ItemNum" ` IF cClassificado = "ItemNum"
THEN "SELECTED" ELSE "" `>Item</OPTION>
<OPTION VALUE="ItemName" ` IF cClassificado = "ItemName"
THEN "SELECTED" ELSE "" `>Nome</OPTION>
</SELECT>
</TD>
<TD>
<INPUT TYPE="Submit" NAME="SubmitSearch" Value="Pesquisa">
</TD>
</TR>
</TABLE>
</FORM>
<!-- End of Search Form -->
<script language="SpeedScript">
IF lPesquisa THEN DO:
hQueryItem:QUERY-OPEN.
IF hQueryItem:NUM-RESULTS = 0 AND REQUEST_METHOD = "POST" THEN
queue-message("Pesquisa","No existe dados para essa pesquisa.<br>").
/* Mostrar resultado se existir */
IF hQueryItem:NUM-RESULTS > 0 AND REQUEST_METHOD = "POST" THEN DO:
</script>
<!-- Results List -->
<TABLE WIDTH="90%" ALIGN="Center" BORDER="1">
<TR>
<TH WIDTH="20%">Numero do Item</TH>
<TH WIDTH="40%">Nome do Item</TH>
<TH WIDTH="20%">Valor</TH>
<TH WIDTH="20%">Quantidade</TH>
</TR>
<script language="SpeedScript">
REPEAT:
hQueryItem:GET-NEXT.
IF (hQueryItem:QUERY-OFF-END) THEN LEAVE.
</script>
<TR>
<TD><B>` Item.ItemNum `</B></TD>
<TD>` Item.ItemName `</TD>
<TD ALIGN="Right">` Item.Price `</TD>
<TD ALIGN="RIGHT">` Item.OnHand `</TD>

SPEEDSCRIPT

</TR>
<TR>
<TD>&nbsp</TD>
<TD COLSPAN=3>
` Item.CatDescription `
</TD>
</TR>
<script language="SpeedScript">
END. /* REPEAT */
</script>
</TABLE>
<!-- End of Results List -->
<script language="SpeedScript">
END. /* If hQueryItem:Num-Results > 0 */
END. /* IF lPesquisa */
IF available-messages("ItemSearch") THEN DO:
{&OUT} '<CENTER><B><FONT COLOR="RED">' get-messages("ItemSearch", TRUE)
'</FONT></B></CENTER>'.
END. /* if available-messages */
</script>
cTipoPesquisa
cPesquisaPor
cClassificado
cPesquisa
cWhere
cSort

`
`
`
`
`
`

cTipoPesquisa `
cPesquisaPor `
cClassificado `
cPesquisa `
cWhere `
cSort `

<br>
<br>
<br>
<br>
<br>
<br>

</body>
</html>
Exemplo localizado em: exemplo/capitulo5/exemplo13-08.html

O resultado final de uma pesquisa de registro fica:

CGI WRAPPER

6. CGI Wrapper
6.1. CONHECENDO O CGI WRAPPER
O cdigo fonte do objeto WEB CGI Wrapper um arquivo (.w) SpeedScript, sem estar
associado a nenhum cdigo fonte HTML. O Rcode criado pela compilao do programa fonte
(.w) executado pelo agente do WebSpeed. Quando o objeto WEB CGI Wrapper executado,
um arquivo HTML criado dinamicamente com as informaes corretas para serem mostradas
em um browser.
O CGI Wrapper utiliza o preprocessador {&OUT} na procedure interna process-web-request
para gerar uma pgina WEB (HTML) vlida. Este HTML final possui um cabealho gerado pelo
prprio CGI Wrapper.
Para usar o CGI Wrapper, existe uma template no AppBuilder prpria para isso. Esta template
possui o corpo do SpeedScript para gerar e criar um arquivo HTML para o browser.

6.2. ESTRUTURA DO CGI WRAPPER


O CGI Wrapper tem como resultado praticamente o mesmo que o SpeedScript, uma pgina
WEB. Entretanto, enquanto o SpeedScript escrito como um HTML e possui inseres de
cdigo Progress atravs da tag SCRIPT para tornar o HTML dinmico, o CGI Wrapper escrito
diretamente em Progress e sua sada, que utiliza o preprocessador {&OUT}, o faz para o
HTML, mantendo o dinamismo.
Preprocessador {&OUT}
O redirecionamento feito por esse preprocessador para o HTML automtico. Entretanto, para
que o resultado da pgina executada no browser seja de acordo com o desejado, necessrio
colocar todas as tags que o browser precisaria para montar a pgina corretamente. Todo o
processo de saltar as linhas, as cores e os estilos devero estar montados na string a ser
mostrada.
{&OUT} "<CENTER><B>Exemplo de Sada para WEB</B></CENTER><BR>" SKIP
"O primeiro cliente da tabela Customer :<B>" customer.name SKIP
"</B>.<BR>".

Neste exemplo, o comando SKIP no causa quebra de linha no browser. Isso feito pelas tags
<BR> dos textos montados.

6.2.1. Estrutura de um CGI Wrapper


O CGI Wrapper um programa estruturado e pode ser dividido em procedures e funes
internas. Para facilitar, existe um template Progress que monta um ambiente dividido em:
Definitions
Main Block
Procedure OutputHeader
Process-Web-Request

CGI WRAPPER

Definitions
Nesta rea devem ser adicionadas todas as definies de variveis, parmetros e objetos que
devero ser usados pelo programa.
Main Block
O Main Block inicializa variveis e executa procedures e funes que devem ser disparadas
logo na execuo do programa, como o caso da procedure interna Process-Web-Request.
No Main Block, pode-se colocar todo o cdigo que deve ser executado antes ou depois da
execuo da procedure Process-Web-Request. Basicamente, isso faz com que parte do cdigo
seja colocada antes da sada do HTML e parte depois.
Procedure OutputHeader
Esta procedure interna semelhante procedure interna Output-Header usada no
SpeedScript. Nesta procedure interna possvel setar alguns cookies e outros estados de uma
requisio WEB. Esta procedure interna executada dentro de outra procedure interna; a
Process-Web-Request.
A principal diferena dessa procedure interna em relao a existente no modelo SpeedScript,
que essa procedure interna j vem includa automaticamente no template CGI Wrapper.
Procedure Process-Web-Request
Esta a principal procedure interna do CGI Wrapper, pois ela que inicia a gerao da sada
HTML para a pgina WEB. Nesta procedure esto as tags que iniciam uma pgina (<HTML>,
<HEAD> e <BODY>) assim como as respectivas tags que encerram a pgina (</BODY>,
</HEAD> e </HTML>). No intervalo entre essas tags deve ser colocado todo o texto referente
montagem da pgina WEB.
nesta procedure interna que a lgica referente leitura dos dados deve ser feita, e a sada
dessas informaes deve ser feita direcionada para WEB, com o uso do {&OUT} por exemplo.

6.2.2. Processamento do CGI Wrapper


O processamento de um programa desenvolvido em CGI Wrapper basicamente passa por
todas as sees.
1. Definitions
2. Main Block (Executando a procedure interna Process-Web-Request)
3. Process-Web-Request (Executando a procedure interna OutputHeader)

CGI WRAPPER

4. OutputHeader
5. Process-Web-Request (Aps a execuo da procedure interna OutputHeader)
6. Main Block (Aps a execuo da procedure interna Process-Web-Request).

6.3. EXEMPLO COMPLETO DO CGI WRAPPER


O exemplo basicamente a construo de uma aplicao como um carrinho de compras pela
internet. Todos os passos sero descritos para melhor entender como trabalhar com esse tipo
de template WEB.
Basicamente, este desenvolvimento ser feito nesta ordem:
-

Primeiramente deve-se selecionar um cliente (tabela Customer)


Validar se esse cliente est correto
Criar uma ordem para esse cliente (tabela Order)
Selecionar os nmeros dos itens para adicionar a essa ordem (tabela Item)
Validar os nmeros dos itens
Entrar com a quantidade para cada item
Eliminar itens selecionados
Salvar essa ordem e possibilitar a entrada de uma nova ordem.

1 Seleo da template CGI Wrapper. Como uma template padro para auxiliar o
desenvolvimento dos programas, selecion-la no AppBuilder. Para isto, acessar o boto NEW
ou as opes FILE e NEW do menu.

Ao abrir a janela de opes, selecionar o CGI Wrapper. Esta opo trar uma template com
definies iniciais.

CGI WRAPPER

2 Para este programa, algumas variveis devem ser criadas. Essas variveis devem ser
usadas para utilizao de cookies e atribuio de valores para os totais.
Seo DEFINITIONS
/*-----------------------------------------------------------------------Arquivo : compras.p
Descrio: Carrinho de Compras em CGI Wrapper
Autor
: SQLWorks Consultoria Ltda.
------------------------------------------------------------------------*/
/*
This .W file was created with the Progress AppBuilder.
*/
/*----------------------------------------------------------------------*/
/* Create an unnamed pool to store all the widgets created
by this procedure. This is a good default which assures
that this procedure's triggers and internal procedures
will execute in this procedure's storage, and that proper
cleanup will occur on deletion of the procedure. */
CREATE WIDGET-POOL.
/* *************************** Definitions
/* Parameters Definitions --/* Local Variable Definitions --DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE

VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE

cStatusCorrente
iOrdemCorrente
iClienteCorrente
iItemCorrente
iQtdeCorrente
dePrecoTotal
iOrderLine

AS
AS
AS
AS
AS
AS
AS

************************** */
*/
*/

CHARACTER
INTEGER
INTEGER
INTEGER
INTEGER
DECIMAL
INTEGER

NO-UNDO.
NO-UNDO.
NO-UNDO.
NO-UNDO.
NO-UNDO.
NO-UNDO.
NO-UNDO.

Exemplo localizado em: exemplo/capitulo6/exemplo14.p

A varivel cStatusCorrente possui valores que representam o que foi processado. Como a cada
processo, todo o programa executado novamente, importante identificar qual ao se
deseja realizar. Essa varivel possui um desses 4 valores.
Valor Armazenado
Descrio
SelecionandoCliente Nmero do cliente entrado
AdicionandoLinha
Selecionando um nmero de item para adicionar

CGI WRAPPER

EditandoLinha
Confirmando

Entrando com a quantidade para a ordem


Reanalisando e salvando a ordem.

As demais variveis so necessrias para o processo da lgica do carrinho de compras, como


armazenar nmero do cliente, do pedido e do item, quantidades e preos.
3 Colocar no Main Block um comando CASE para processar as informaes de entrada
baseando-se no valor da varivel cStatusCorrente. Alm de ler os valores dos cookies.
/* ************************ Main Code Block *********************** */
/* Atualizao de variveis de cookies ou campos */
ASSIGN cStatusCorrente
iClienteCorrente
iOrdemCorrente
ASSIGN iItemCorrente
ASSIGN iQtdeCorrente

=
=
=
=
=

GET-VALUE("StatusCorrente")
INT(GET-VALUE("ClienteCorrente"))
INT(GET-VALUE("OrdemCorrente")).
INT(GET-VALUE("ItemCorrente")) NO-ERROR.
INT(GET-VALUE("Qtde")) NO-ERROR.

/* Altera o cStatusCorrente da ltima requisio para um novo Status e


monta as mensagens e erros para serem mostrados */
CASE cStatusCorrente:
WHEN "" THEN DO:
/* Set to Select Customer */
ASSIGN cStatusCorrente = "SelecionandoCliente".
END. /* When "" */
WHEN
/*
IF
/*

"SelecionandoCliente" THEN DO:


If a customer was entered or exsists in a cookie then use it */
GET-VALUE("ClienteCorrente") <> "" THEN DO:
Check if entered customer is a valid integer */
ASSIGN iClienteCorrente = INT(GET-VALUE("ClienteCorrente")) NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
queue-message("EntradaOrdem","Entrar um valor vlido para cliente").
ASSIGN iClienteCorrente = ?.
END. /* IF ERROR-STATUS:ERROR */
END. /* IF GET-VALUE("ClienteCorrente") */

/* Se o cliente est disponvel, criar uma nova ordem para o ele */


IF iClienteCorrente ne ? THEN DO:
IF CAN-FIND(Customer WHERE CustNum = iClienteCorrente) THEN DO:
CREATE Order.
ASSIGN Order.CustNum
= iClienteCorrente
IOrdemCorrente = Order.OrderNum
cStatusCorrente = "AdicionandoLinha".
END. /* IF CAN-FIND(Customer) */
ELSE
queue-message("EntradaOrdem", "Cliente no existe.").
END. /* IF iClienteCorrente <> ? */
END. /* WHEN "SelectingCustomer */
WHEN "AdicionandoLinha" THEN DO:
/* Pegar o nmero do item corrente da entrada de dados */
ASSIGN iItemCorrente = INT(GET-VALUE("ItemCorrente")) NO-ERROR.
IF iItemCorrente > 0
AND
CAN-FIND(Item WHERE Item.ItemNum = iItemCorrente) THEN
ASSIGN cStatusCorrente = "EditandoLinha".
ELSE DO:
IF GET-VALUE("AcaoCorrente") = "" OR
GET-FIELD("ItemCorrente") > "" THEN
queue-message("EntradaOrdem","Item no encontrado.").
END. /* ELSE DO: */
END. /* WHEN "AdicionandoLinha" */

CGI WRAPPER

WHEN "EditandoLinha" THEN DO:


/* Pega a quantidade do campo de entrada e o item de um campo escondido */
IF iQtdeCorrente > 0 THEN DO:
/* Se a quantidade apropriada, cria uma nova linha para a ordem */
CREATE OrderLine.
FIND Item WHERE Item.ItemNum = INT(GET-VALUE("ItemCorrente"))
NO-LOCK NO-ERROR.
ASSIGN iOrderLine
= proximaOrderLine(iOrdemCorrente)
OrderLine.ItemNum
= Item.ItemNum
OrderLine.ExtendedPrice = iQtdeCorrente * Item.Price
OrderLine.LineNum
= iOrderLine
OrderLine.OrderNum
= iOrdemCorrente
OrderLine.Price
= Item.Price
OrderLine.Qty
= iQtdeCorrente
cStatusCorrente
= "AdicionandoLinha".
END. /* IF iQtdeCorrente > 0 */
ELSE
queue-message("OrdemEntrada","Entrar com uma quantidade vlida.").
END. /* WHEN "EditandoLinha" */
OTHERWISE DO:
END. /* OTHERWISE DO */
END CASE.
/* Localizar registro corrente para Customer e Order */
IF iClienteCorrente <> ? THEN
FIND Customer WHERE Customer.CustNum = iClienteCorrente NO-LOCK NO-ERROR.
IF iOrdemCorrente <> ? THEN
FIND ORDER WHERE Order.OrderNum = iOrdemCorrente NO-LOCK NO-ERROR.
/* Process the latest Web event. */
RUN process-web-request.
Exemplo localizado em: exemplo/capitulo6/exemplo14-01.p

Essa procedure apresentar um erro na compilao, pois a funo ProximaOrderLine ainda


no foi definida no exemplo.
O comando CASE usado, possui uma atividade para cada opo:
Valor de cStatusCorrente
Cdigo no comando CASE
Vazio
Atualiza o cStatusCorrente para SelecionandoCliente. E
executado quando o programa executado pela primeira vez.
SelecionandoCliente
Verifica o nmero do campo HTML (CustomerCorrente) como um
nmero vlido de Customer que pode ser encontrado na tabela de
Customer.
Se o Customer for vlido, um registro de ordem criado e este
nmero de Customer atualizado na ordem. Alm do prprio valor
da ordem.

AdicionandoLinha

EditandoLinha

A varivel cStatusCorrente alterada para AdicionandoLinha.


Verifica se o nmero do Item digitado no campo do HTML vlido
para a tabela de Item.
Se o item localizado, o nmero do item adicionado na varivel
iItemCorrente e o valor de cStatusCorrente atualizado para
EditandoLinha.
Verifica se a quantidade que foi entrada vlida e cria uma
OrderLine e atualiza seus campos.
Uma vez adicionado, a varivel cStatusCorrente atualizada para

CGI WRAPPER

AdicionandoLinha para preparar a tela para entrar com outro item.


4 A procedure interna Process-Web-Request inicia a sada da pgina HTML. Essa procedure
executa um comando CASE baseado na varivel cStatusCorrente. Cada opo do CASE
executa uma procedure interna para atender ao status. Os contedos dessas procedures
internas sero descritos posteriormente. Outra procedure interna executada a OrderHeader,
onde criar o cabealho do pedido.
/*----------------------------------------------------------------------------Purpose:
Process the web request.
Parameters: <none>
Notes:
-----------------------------------------------------------------------------*/
/*
* Output the MIME header and set up the object as state-less or state-aware.
* This is required if any HTML is to be returned to the browser.
*/
RUN outputHeader.
/* ********************************************************************
Output Top of Order Entry Screen including the start of the Form
************************************************************************ */
{&OUT} "<HTML>":U SKIP
"<HEAD>":U SKIP
"<TITLE> Carrinho de Compra </TITLE>":U SKIP
"</HEAD>":U SKIP
"<BODY>":U SKIP.
{&OUT} '<FORM NAME="ShopCart" METHOD="POST">' SKIP.
RUN OrderHeader.
/**************************************************************************
Output Appropriate Screen based on Current Status
***************************************************************************/
/* Output proper Screen based on Current Status */
CASE cStatusCorrente:
WHEN "SelecionandoCliente" THEN DO:
RUN piSelecionandoCliente.
END.
WHEN "AdicionandoLinha" THEN DO:
RUN piAdicionandoLinha.
END.
WHEN "EditandoLinha" THEN DO:
RUN piEditandoLinha.
END.
WHEN "Confirmando" THEN DO:
RUN piConfirmando.
END.
END CASE.
{&OUT} '</FORM>' SKIP.
RUN OutputErrors.
/******************************************************************************
Output the Existing Line Items and Finish the Page
************************************************************************** */
IF cStatusCorrente <> "Confirmando" THEN DO:
RUN piOrderLines.
END.

CGI WRAPPER

{&OUT} cStatusCorrente.
{&OUT}
"</BODY>":U SKIP
"</HTML>":U SKIP.
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-02.p

Essa procedure ainda apresentar um erro na compilao, pois a funo ProximaOrderLine


ainda no foi definida no exemplo.
5 A procedure interna OutputHeader ser alterada para atualizar alguns cookies. Estes
cookies sero usados para usar informaes entre cada requisio da pgina.
/*---------------------------------------------------------------------------Purpose:
Output the MIME header, and any "cookie" information needed
by this procedure.
Parameters: <none>
Notes:
In the event that this Web object is state-aware, this is
a good place to set the webState and webTimeout attributes.
----------------------------------------------------------------------------*/
RUN SetCookie IN web-utilities-hdl("CustomerCorrente",
STRING(iClienteCorrente), ?, ?, ?, ?, ?).
RUN SetCookie IN web-utilities-hdl("OrdemCorrente",
STRING(iOrdemCorrente), ?, ?, ?, ?, ?).
RUN SetCookie IN web-utilities-hdl("ItemCorrente",
STRING(iItemCorrente), ?, ?, ?, ?, ?).
output-content-type ("text/html":U).
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-03.p

Essa procedure ainda apresentar um erro na compilao, pois a funo ProximaOrderLine


ainda no foi definida no exemplo.
Esses cookies recebem os seguintes valores:
Cookie
Valor
CustomerCorrente Se o campo HTML CustomerCorrente submetido, este valor setado
como o novo Nmero de Cliente. Se este campo no existe, o cookie no
altera o valor e mantm o Customer corrente.
OrderCorrente
Uma vez criado a Ordem, este cookie alterado para o nmero da ordem.
Este cookie usado para recuperar a ordem corrente em cada requisio.
Se outra ordem adicionada, este valor do cookie alterado para o novo
nmero da ordem.
ItemCorrente
Quando um nmero de Item selecionado, este cookie armazena o valor
at a quantidade ser digitada e uma OrderLine ser criada.
6 Uma funo para o prximo item da ordem deve ser criada. Esta funo a
proximaOrderLine e retorna o nmero do prximo item da ordem.
RETURNS INTEGER
(INPUT OrderNum AS INTEGER):
/*---------------------------------------------------------------------------Purpose:
Notes:
----------------------------------------------------------------------------*/
DEFINE BUFFER bOrderLine FOR OrderLine.
DEFINE VARIABLE iOrderLine AS INTEGER NO-UNDO.

CGI WRAPPER

FOR EACH bOrderLine WHERE bOrderLine.OrderNum = OrderNum NO-LOCK


BY OrderLine.LineNum:
ASSIGN iOrderLine = bOrderLine.LineNum.
END.
ASSIGN iOrderLine = iOrderLine + 1.
RETURN iOrderLine.
/* Function return value. */
END FUNCTION.
Exemplo localizado em: exemplo/capitulo6/exemplo14-04.p

Com a criao da funo proximaOrderLine, o erro de compilao est solucionado. Entretanto,


o programa ainda no pode ser executado, pois como a procedure OrderHeader no foi criada,
um erro ocorre no momento da execuo.
7 Criar a procedure interna OrderHeader. Essa procedure construir o cabealho com os
campos Nmero do Cliente, Nome do Cliente, Nmero da Ordem e o boto de confirma. Nesta
procedure ainda existir um campo escondido que atualizando a varivel cStatusCorrente de
uma requisio para outra.
Nesta lgica, ser desenhada a sada HTML.
A sada para o HTML usar o preprocessador {&OUT}.
Aspas simples sero usadas para delimitar os textos e as aspas duplas os contedos
do HTML que devem estar entre aspas.
As informaes dinmicas, como valores de variveis e de campos, devem ser
concatenadas as strings existentes no HTML. Entretanto deve-se tratar se os registros
esto disponveis no caso de uso de campos.
/*---------------------------------------------------------------------------Purpose:
Parameters: <none>
Notes:
----------------------------------------------------------------------------*/
/* Output the current status as a hidden field */
{&OUT} '<INPUT TYPE="HIDDEN"
NAME="StatusCorrente"
VALUE="' cStatusCorrente '">' SKIP.
{&OUT} '<TABLE ALIGN="CENTER" WIDTH="90%">' SKIP
'<TR>'
SKIP
'<TD ALIGN="RIGHT"> Customer: </TD>' SKIP
'<TD>'
IF AVAILABLE Customer THEN STRING(Customer.CustNum)
ELSE ""
'</TD>'
SKIP
'<TD ALIGN="RIGHT">Name: </TD>'
SKIP
'<TD>'
IF AVAILABLE Customer THEN Customer.Name
ELSE ""
'</TD>'
SKIP
'<TD ALIGN="RIGHT"> Order: </TD>'
SKIP
'<TD>'
IF AVAILABLE Order THEN STRING(Order.OrderNum)
ELSE ""
'</TD>'
SKIP
'<TD>'
SKIP
'<INPUT TYPE="SUBMIT"
NAME="CheckOut"
VALUE="Check Out">'
SKIP
'</TD>'
SKIP
'</TR>'
SKIP
'</TABLE>'
SKIP

CGI WRAPPER

'<HR>'

SKIP.

END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-05.p

Com a criao da procedure OrderHeader, este erro de execuo est solucionado. Entretanto,
outro erro apresentado na execuo do programa, pois a procedure piSelecionandoCliente
no foi criada.
8 Criar a procedure interna OutputErrors. Esta procedure ir mostrar as mensagens enfileiras
pela funo get-messages().
A execuo dessa procedure colocada na procedure Process-Web-Request, logo aps o
comando CASE e antes da sada do OrderLines.
/*---------------------------------------------------------------------------Purpose:
Parameters: <none>
Notes:
----------------------------------------------------------------------------*/
IF available-messages("OrdemEntrada") THEN DO:
{&OUT} '<CENTER><B><FONT COLOR="RED">'
get-messages("OrdemEntrada", TRUE)
'</FONT></B></CENTER>'.
END. /* if available-messages */
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-06.p

Entretanto, ao tentar executar, o problema da procedure piSelecionandoCliente persiste.


9 Criar a procedure interna piSelecionandoCliente. Ao aceitar a entrada do nmero do cliente,
o campo CustomerCorrente lido nessa procedure.
Este cdigo cria o campo ClienteCorrente e o boto de ENTER para submeter o nmero
digitado.
/*---------------------------------------------------------------------------Purpose:
Parameters: <none>
Notes:
----------------------------------------------------------------------------*/
{&OUT} '<TABLE ALIGN="CENTER">'
SKIP
'<TR>'
SKIP
'<TD> Entre com o Nmero do Cliente </TD>'
SKIP
'<TD><INPUT TYPE="Text" Name="ClienteCorrente"></TD>' SKIP
'<TD><INPUT TYPE="Submit" Value="Enter"></TD>'
SKIP
'</TR>'
SKIP
'</TABLE>'
SKIP.
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-07.p

Com a criao da procedure piSelecionandoCliente, este erro de execuo est solucionado.


Entretanto, agora o erro apresentado na execuo do programa est na procedure
piOrderLines que ainda no foi criada.
10 Criar a procedure interna piAdicionandoLinha. Uma vez selecionado o cliente, o comando
CASE do MAIN BLOCK cria a ordem e altera a varivel cStatusCorrente para
AdicionandoLinha. Este status executar a procedure interna piAdicionandoLinha que
usada para criar a entrada do nmero do item.

CGI WRAPPER

Esta procedure tambm possui a criao do boto de confirmao chamado getItem com o
valor Add.
/*---------------------------------------------------------------------------Purpose:
Parameters: <none>
Notes:
----------------------------------------------------------------------------*/
{&OUT} '<TABLE BORDER="1">'
SKIP
'<TR>'
SKIP
'<TD>Item Number:</TD>'
SKIP
'<TD><INPUT TYPE="TEXT" NAME="ItemCorrente"></TD>'
SKIP
'<TD><INPUT TYPE="SUBMIT" NAME="GetItem" VALUE="Add"></TD>' SKIP
'</TR>'
SKIP
'</TABLE>'
SKIP.
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-08.p

O erro apresentado na execuo do programa ainda est na procedure piOrderLines que no


foi criada.
11 Criar a procedure interna piEditandoLinha. Uma vez selecionado o item, o cookie
ItemCorrente armazena para o prximo passo para a entrada de dados. Esta lgica cria uma
entrada para a quantidade da linha, alm de encontrar o item que foi selecionado para o
prximo passo.
/*---------------------------------------------------------------------------Purpose:
Parameters: <none>
Notes:
----------------------------------------------------------------------------*/
FIND Item WHERE Item.ItemNum = iItemCorrente NO-LOCK NO-ERROR.
{&OUT} '<TABLE BORDER="1" WIDTH="100%">'
SKIP
'<TR>'
SKIP
'<TD WIDTH="25%" ALIGN="CENTER">'
SKIP
'Nmero do Item: ' Item.ItemNum
SKIP
'</TD>'
SKIP
'<TD WIDTH="25%" ALIGN="CENTER">'
SKIP
'Preo: ' STRING(Item.Price, "$>>>>>>>9.99")
SKIP
'</TD>'
SKIP
'<TD WIDTH="25%" ALIGN="CENTER">'
SKIP
'Quantidade: '
SKIP
'<INPUT TYPE="TEXT" SIZE="3" NAME="QTDE">'
SKIP
'</TD>'
SKIP
'<TD WIDTH="25%" ALIGN="CENTER">'
SKIP
'<INPUT TYPE="Submit" NAME="SaveLine" Value="SALVAR">' SKIP
'</TD>'
SKIP
'</TR>'
SKIP
'<TR>'
SKIP
'<TD>&nbsp;</TD>'
SKIP
'<TD COLSPAN="3">'
SKIP
Item.CatDescription
SKIP
'</TD>'
SKIP
'</TR>'
SKIP
'</TABLE>'
SKIP.
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-09.p

O erro apresentado na execuo do programa ainda est na procedure piOrderLines que no


foi criada.

CGI WRAPPER

12 Criar a procedure interna piOrderLines. Esta procedure interna para criar uma tabela com
linhas para cada order-line que foi adicionada ordem corrente. Nesta procedure tambm ser
criado um boto de delete para eliminar o item existente.
Como para cada linha existe um boto de delete, necessrio ter um campo HTML escondido
contendo o nmero da linha a ser eliminada. Como existe um boto para cada linha, somente a
linha onde est o boto ser eliminada.
Est lgica ainda possui algumas caractersticas:
As linhas do cabealho e do rodap, que possui um totalizador, ficam fora do escopo
do loop da leitura dos Order-Line.
Para cada linha criado um campo escondido no formulrio para armazenar o nmero
da linha.
O acumulado dos preos mostrado na ltima linha da tabela.
O item encontrado para cada linha da ordem, tem sua descrio impressa.
/*---------------------------------------------------------------------------Purpose:
Parameters: <none>
Notes:
----------------------------------------------------------------------------*/
IF CAN-FIND(FIRST OrderLine WHERE
OrderLine.OrderNum = iOrdemCorrente) THEN DO:
{&OUT} '<HR>'
SKIP
'<TABLE WIDTH="100%" BORDER="1">' SKIP
'<TR>'
SKIP
'<TH WIDTH="15%">&nbsp;</TH>'
SKIP
'<TH WIDTH="15%">Linha</TH>'
SKIP
'<TH WIDTH="15%">Item</TH>'
SKIP
'<TH WIDTH="20%">Preo</TH>'
SKIP
'<TH WIDTH="15%">Qtde</TH>'
SKIP
'<TH WIDTH="20%">Extendido</TH>' SKIP
'</TR>'
SKIP.
FOR EACH OrderLine WHERE OrderLine.OrderNum = iOrdemCorrente NO-LOCK:
ASSIGN dePrecoTotal = dePrecoTotal + OrderLine.ExtendedPrice.
FIND Item WHERE Item.ItemNum = OrderLine.ItemNum NO-LOCK NO-ERROR.
{&OUT} '<TR>'
SKIP
'<FORM METHOD="POST">'
SKIP
'<TD ALIGN="CENTER">'
SKIP
'<INPUT TYPE="Submit"
Name="LineAction"
Value="Delete">'
SKIP
'<INPUT Type=Hidden
Name="LineNum"
Value="' OrderLine.LineNum '">'
SKIP
'</TD>'
SKIP
'<TD ALIGN="CENTER">' OrderLine.LineNum '</TD>'
SKIP
'<TD ALIGN="CENTER">' OrderLine.ItemNum '</TD>'
SKIP
'<TD ALIGN="RIGHT">'
STRING(OrderLine.Price, "$>>>>>9.99")
'</TD>'
SKIP
'<TD ALIGN="CENTER">' OrderLine.Qty '</TD>'
SKIP
'<TD ALIGN="RIGHT">'
STRING(OrderLine.ExtendedPrice, "$>>>>>>9.99")
'</TD>'
SKIP
'</TR>'
SKIP
'<TR>'
SKIP
'<TD COLSPAN="2">&nbsp;</TD>'
SKIP
'<TD COLSPAN="4">' Item.CatDescription '</TD>'
SKIP
'</FORM></TR>'
SKIP.
END.

CGI WRAPPER

{&OUT} '<TR>'
'<TD COLSPAN="4">&nbsp;</TD>'
'<TD ALIGN="Right"><B>Total</B></TD>'
'<TD ALIGN="Center"><B>'
String(dePrecoTotal, "$>>>>>>9.99")
'</B></TD>'
'</TR>'

SKIP
SKIP
SKIP
SKIP
SKIP.

{&OUT} '</TABLE>' SKIP


'<HR>'
SKIP.
END.
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-10.p

13 Quando o boto de delete for disparado, dois pares de nomes e valores so submetidos
com o formulrio para o item. O primeiro nomeado como LineAction e tem o valor de Delete
e o segundo tem o nome de LineNum e tem o valor do nmero da linha, que um campo
escondido.
Para realizar o delete, a funo get-value() deve ser usado para identificar quando o boto de
delete foi clicado. O cdigo MAIN BLOCK deve ser alterado depois do comando de atualizao
para receber o cdigo de delete do registro e deve alterar a varivel cStatusCorrente para
ItemEliminado.
/* ************************ Main Code Block *********************** */
/* Atualizao de variveis de cookies ou campos */
ASSIGN cStatusCorrente
iClienteCorrente
iOrdemCorrente
ASSIGN iItemCorrente
ASSIGN iQtdeCorrente

=
=
=
=
=

GET-VALUE("StatusCorrente")
INT(GET-VALUE("ClienteCorrente"))
INT(GET-VALUE("OrdemCorrente")).
INT(GET-VALUE("ItemCorrente")) NO-ERROR.
INT(GET-VALUE("Qtde")) NO-ERROR.

/* Delete Action */
IF GET-VALUE("LineAction") = "DELETE" THEN DO TRANS:
FIND OrderLine WHERE OrderLine.OrderNum = iOrdemCorrente AND
OrderLine.LineNum = INT(GET-VALUE("LineNum"))
EXCLUSIVE-LOCK NO-ERROR.
IF AVAILABLE OrderLine THEN
DELETE OrderLine.
queue-message("OrdemEntrada","A OrderLine foi eliminado").
ASSIGN cStatusCorrente = "ItemEliminado".
END.
/* Altera o cStatusCorrente da ltima requisio para um novo Status e
monta as mensagens e erros para serem mostrados */
CASE cStatusCorrente:
WHEN "" THEN DO:
/* Set to Select Customer */
ASSIGN cStatusCorrente = "SelecionandoCliente".
END. /* When "" */
WHEN
/*
IF
/*

"SelecionandoCliente" THEN DO:


If a customer was entered or exsists in a cookie then use it */
GET-VALUE("ClienteCorrente") <> "" THEN DO:
Check if entered customer is a valid integer */
ASSIGN iClienteCorrente = INT(GET-VALUE("ClienteCorrente")) NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
queue-message("EntradaOrdem","Entrar um valor vlido para cliente").

CGI WRAPPER

ASSIGN iClienteCorrente = ?.
END. /* IF ERROR-STATUS:ERROR */
END. /* IF GET-VALUE("ClienteCorrente") */
/* Se o cliente est disponvel, criar uma nova ordem para o ele */
IF iClienteCorrente <> ? THEN DO:
IF CAN-FIND(Customer WHERE CustNum = iClienteCorrente) THEN DO:
CREATE ORDER.
ASSIGN ORDER.CustNum
= iClienteCorrente
IOrdemCorrente = Order.OrderNum
cStatusCorrente = "AdicionandoLinha".
END. /* IF CAN-FIND(Customer) */
ELSE
queue-message("EntradaOrdem", "Cliente no existe.").
END. /* IF iClienteCorrente <> ? */
END. /* WHEN "SelectingCustomer */
WHEN "AdicionandoLinha" THEN DO:
/* Pegar o nmero do item corrente da entrada de dados */
ASSIGN iItemCorrente = INT(GET-VALUE("ItemCorrente")) NO-ERROR.
IF iItemCorrente > 0
AND
CAN-FIND(Item WHERE Item.ItemNum = iItemCorrente) THEN
ASSIGN cStatusCorrente = "EditandoLinha".
ELSE DO:
IF GET-VALUE("AcaoCorrente") = "" OR
GET-FIELD("ItemCorrente") > "" THEN
queue-message("EntradaOrdem","Item no encontrado.").
END. /* ELSE DO: */
END. /* WHEN "AdicionandoLinha" */
WHEN "EditandoLinha" THEN DO:
/* Pega a quantidade do campo de entrada e o item de um campo escondido */
IF iQtdeCorrente > 0 THEN DO:
/* Se a quantidade apropriada, cria uma nova linha para a ordem */
CREATE OrderLine.
FIND Item WHERE Item.ItemNum = INT(GET-VALUE("ItemCorrente"))
NO-LOCK NO-ERROR.
ASSIGN iOrderLine
= proximaOrderLine(iOrdemCorrente)
OrderLine.ItemNum
= Item.ItemNum
OrderLine.ExtendedPrice = iQtdeCorrente * Item.Price
OrderLine.LineNum
= iOrderLine
OrderLine.OrderNum
= iOrdemCorrente
OrderLine.Price
= Item.Price
OrderLine.Qty
= iQtdeCorrente
cStatusCorrente
= "AdicionandoLinha".
END. /* IF iQtdeCorrente > 0 */
ELSE
queue-message("OrdemEntrada","Entrar com uma quantidade vlida.").
END. /* WHEN "EditandoLinha" */
WHEN "EliminandoItem" THEN DO:
ASSIGN cStatusCorrente = "AdicionandoLinha".
END. /* WHEN "EliminandoItem" */
OTHERWISE DO:
END. /* OTHERWISE DO */
END CASE.
/* Localizar registro corrente para Customer e Order */
IF iClienteCorrente <> ? THEN
FIND Customer WHERE Customer.CustNum = iClienteCorrente NO-LOCK NO-ERROR.
IF iOrdemCorrente <> ? THEN
FIND ORDER WHERE Order.OrderNum = iOrdemCorrente NO-LOCK NO-ERROR.
/* Process the latest Web event. */
RUN process-web-request.
Exemplo localizado em: exemplo/capitulo6/exemplo14-11.p

CGI WRAPPER

14 Quando o boto de Confirmao for selecionado, a funo GET-FUNCTION() ser usada


para identificar este evento, onde o status atual ser alterado para Confirmado e executado a
procedure piConfirmado na Process-Web-Request.
O cdigo MAIN BLOCK deve ser alterado antes do comando CASE.
Outro cdigo a ser adicionado no MAIN BLOCK, mas logo aps os comandos ASSIGN, a
verificao de uma nova ordem, alterando o status corrente para SelecionandoCliente. Para
iniciar uma outra ordem, o valor do cookie OrdemCorrente deve ser limpo para ser criado para
o outro valor.
/* ************************ Main Code Block *********************** */
/* Atualizao de variveis de cookies ou campos */
ASSIGN cStatusCorrente
iClienteCorrente
iOrdemCorrente
ASSIGN iItemCorrente
ASSIGN iQtdeCorrente

=
=
=
=
=

GET-VALUE("StatusCorrente")
INT(GET-VALUE("ClienteCorrente"))
INT(GET-VALUE("OrdemCorrente")).
INT(GET-VALUE("ItemCorrente")) NO-ERROR.
INT(GET-VALUE("Qtde")) NO-ERROR.

IF GET-VALUE("NovaOrdem") <> "" THEN DO:


ASSIGN cStatusCorrente = "SelecionandoCliente"
iOrdemCorrente = ?.
END.
/* Delete Action */
IF GET-VALUE("LineAction") = "DELETE" THEN DO TRANS:
FIND OrderLine WHERE OrderLine.OrderNum = iOrdemCorrente AND
OrderLine.LineNum = INT(GET-VALUE("LineNum"))
EXCLUSIVE-LOCK NO-ERROR.
IF AVAILABLE OrderLine THEN
DELETE OrderLine.
queue-message("OrderEntrada","OrderLine foi eliminado").
ASSIGN cStatusCorrente = "ItemEliminado".
END.
IF GET-VALUE("CheckOut") <> "" THEN DO:
ASSIGN cStatusCorrente = "Confirmando".
END.
/* Altera o cStatusCorrente da ltima requisio para um novo Status e
monta as mensagens e erros para serem mostrados */
CASE cStatusCorrente:
WHEN "" THEN DO:
/* Set to Select Customer */
ASSIGN cStatusCorrente = "SelecionandoCliente".
END. /* When "" */
WHEN
/*
IF
/*

"SelecionandoCliente" THEN DO:


If a customer was entered or exsists in a cookie then use it */
GET-VALUE("ClienteCorrente") <> "" THEN DO:
Check if entered customer is a valid integer */
ASSIGN iClienteCorrente = INT(GET-VALUE("ClienteCorrente")) NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
queue-message("EntradaOrdem","Entrar um valor vlido para cliente").
ASSIGN iClienteCorrente = ?.
END. /* IF ERROR-STATUS:ERROR */
END. /* IF GET-VALUE("ClienteCorrente") */
/* Se o cliente est disponvel, criar uma nova ordem para ele */
IF iClienteCorrente <> ? THEN DO:

CGI WRAPPER

IF CAN-FIND(Customer WHERE CustNum = iClienteCorrente) THEN DO:


CREATE ORDER.
ASSIGN ORDER.CustNum
= iClienteCorrente
iOrdemCorrente = Order.OrderNum
cStatusCorrente = "AdicionandoLinha".
END. /* IF CAN-FIND(Customer) */
ELSE
queue-message("EntradaOrdem", "Cliente no existe.").
END. /* IF iClienteCorrente <> ? */
END. /* WHEN "SelectingCustomer */
WHEN "AdicionandoLinha" THEN DO:
/* Pegar o nmero do item corrente da entrada de dados */
ASSIGN iItemCorrente = INT(GET-VALUE("ItemCorrente")) NO-ERROR.
IF iItemCorrente > 0
AND
CAN-FIND(Item WHERE item.ItemNum = iItemCorrente) THEN
ASSIGN cStatusCorrente = "EditandoLinha".
ELSE DO:
IF GET-VALUE("AcaoCorrente") = "" OR
GET-FIELD("ItemCorrente") > "" THEN
queue-message("EntradaOrdem","Item no encontrado.").
END. /* ELSE DO: */
END. /* WHEN "AdicionandoLinha" */
WHEN "EditandoLinha" THEN DO:
/* Pega a quantidade do campo de entrada e o item de um campo escondido */
IF iQtdeCorrente > 0 THEN DO:
/* Se a quantidade apropriada, cria uma nova linha para a ordem */
CREATE OrderLine.
FIND Item WHERE Item.ItemNum = INT(GET-VALUE("ItemCorrente"))
NO-LOCK NO-ERROR.
ASSIGN iOrderLine
= proximaOrderLine(iOrdemCorrente)
OrderLine.Itemnum
= Item.ItemNum
OrderLine.ExtendedPrice = iQtdeCorrente * Item.Price
OrderLine.LineNum
= iOrderLine
OrderLine.OrderNum
= iOrdemCorrente
OrderLine.Price
= Item.Price
OrderLine.Qty
= iQtdeCorrente
cStatusCorrente
= "AdicionandoLinha".
END. /* IF iQtdeCorrente > 0 */
ELSE
queue-message("OrdemEntrada","Entrar com uma quantidade vlida.").
END. /* WHEN "EditandoLinha" */
WHEN "EliminandoItem" THEN DO:
ASSIGN cStatusCorrente = "AdicionandoLinha".
END. /* WHEN "EliminandoItem" */
OTHERWISE DO:
END. /* OTHERWISE DO */
END CASE.
/* Localizar registro corrente para Customer e Order */
IF iClienteCorrente <> ? THEN
FIND Customer WHERE Customer.CustNum = iClienteCorrente NO-LOCK NO-ERROR.
IF iOrdemCorrente <> ? THEN
FIND ORDER WHERE Order.OrderNum = iOrdemCorrente NO-LOCK NO-ERROR.
/* Process the latest Web event. */
RUN process-web-request.
Exemplo localizado em: exemplo/capitulo6/exemplo14-12.p

Como o cookie ClienteCorrente alterado e depois recuperado com a funo GETVALUE(ClienteCorrente), o Customer existente usado para criar outra ordem e a varivel
cStatusCorrente alterada para AdicionandoLinha.
15 Criar a procedure interna piConfirmado. Essa procedure dever mostrar informaes das
ordens e atualizar as datas das mesmas.

CGI WRAPPER

/*---------------------------------------------------------------------------Purpose:
Parameters: <none>
Notes:
----------------------------------------------------------------------------*/
FIND Order WHERE Order.Order-Num = iOrdemCorrente EXCLUSIVE-LOCK NO-ERROR.
ASSIGN Order.Order-Date = TODAY.
FOR EACH Order-Line WHERE Order-Line.Order-Num = iOrdemCorrente NO-LOCK:
ASSIGN dePrecoTotal = dePrecoTotal + Order-Line.Extended-Price.
END.
{&OUT} '<TABLE ALIGN="Center" BORDER="1">'
SKIP
'<TR>'
SKIP
'<TD>Nmero do Cliente</TD>'
SKIP
'<TD>' Order.Cust-Num '</TD>'
SKIP
'</TR>'
SKIP
'<TR>'
SKIP
'<TD>Order Number</TD>'
SKIP
'<TD>' Order.Order-Num '</TD>'
SKIP
'</TR>'
SKIP
'<TR>'
SKIP
'<TD>Order Date</TD>'
SKIP
'<TD>' Order.Order-Date '</TD>'
SKIP
'</TR>'
SKIP
'<TR>'
SKIP
'<TD>Order Total</TD>'
SKIP
'<TD>' STRING(dePrecoTotal, "$>>>>>>9.99") '</TD>' SKIP
'</TR>'
SKIP
'<TR>'
SKIP
'<TD COLSPAN="2">'
'<INPUT TYPE=SUBMIT
NAME="NovaOrdem"
VALUE="Entrar com outra Ordem">'
SKIP
'</TD>'
SKIP
'</TR>'
SKIP
'</TABLE>'
SKIP.
END PROCEDURE.
Exemplo localizado em: exemplo/capitulo6/exemplo14-13.p

HTML MAPPING

7. HTML Mapping
7.1. HTML MAPPING
O HTML Mapping possibilita o mapeamento de um layout de um arquivo HTML com os campos
de tabelas de um banco de dados. O SpeedScript gerado processa o gerenciamento da
entrada e sada de dados entre o layout do HTML e os campos do banco de dados. O HTML
Mapping separa a interface de design do HTML da procedure do SpeedScript que interage com
os dados.

7.1.1. HTML Mapping Simples


Este cdigo no possui nenhum SpeedScript embutido, um HTML com um form para entrada
e impresso de dados. Para a comunicao com este HTML, pode-se usar o HTML Mapping
Wizard do AppBuilder. Este template possibilita o mapeamento entre os HTMLs:
Mapear cada campo do tipo INPUT e TEXTAREA com os equivalentes FILL-IN e
EDITOR do banco de dados.
Cria um arquivo OFFSET especificando a posio no form do HTML que mostrado ao
cliente.
Na procedure process-web-request adicionado o comando FIND, como um
SpeedScript.
Salvar o cdigo fonte com o mesmo nome do HTML, mas usando a extenso W.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="SQLWorks Consultoria Ltda">
<TITLE>Localizar Customer</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<H1>Detalhes de Customer</H1>
<FORM ACTION="pagina102.w" METHOD="POST">
<P>
Entre com Customer: <INPUT NAME="CustNum" SIZE="5">
<INPUT TYPE="SUBMIT" NAME="Button" VALUE="Localizar"><BR><BR>
Nome: <INPUT NAME="Name" SIZE="20">
--------Telefone: <INPUT NAME="Phone" SIZE="20"><BR><BR>
Endereco 1: <INPUT NAME="Address" SIZE="20"><BR>
Endereco 2: <INPUT NAME="Address2" SIZE="20"><BR><BR>
Cidade: <INPUT NAME="City" SIZE="12">
---Estado: <INPUT NAME="State" SIZE="20">
---Cep: <INPUT NAME="PostalCode" SIZE="10"><BR><BR>
Comentarios: <TEXTAREA NAME="Comments" ROWS="2" COLS="30"></TEXTAREA>
</P>
</FORM>
</BODY>
</HTML>

HTML MAPPING

Mapeamento entre os Elementos do FORM com o Banco de Dados


Para iniciar esse tratamento, deve-se selecionar a template HTML Mapping Wizard. O Wizard
ir auxiliar na criao do mapeamento dos dados do HTML com o banco de dados.

O passo seguinte solicita o nome do HTML que dever ter o FORM a ser usado. Este nome
pode ser digitado, estando atento ao PROPATH, ou pesquisado pelo boto BROWSE.

Aps indicar o HTML de interface, deve-se selecionar onde os dados devero ser pesquisados.
Esta seleo pode ser de um SmartDataObject ou selecionando diretamente a tabela do banco
de dados. No exemplo proposto, ser selecionada uma tabela do banco de dados. Neste caso,
a opo DATABASE e o boto DEFINE QUERY devem ser selecionados. Ao clicar no boto, a
janela QUERY BUILDER ser aberta para auxiliar na escolha da tabela e suas condies para
montar a QUERY desejada.

HTML MAPPING

O prximo passo auxilia no processo de mapear os campos. Isso pode ser feito
automaticamente, clicando no boto AUTOMAP FIELDS, onde a template tentar
automaticamente relacionar os campos do form do HTML com os campos da tabela
correspondente no banco de dados. Isto possvel caso os nomes dos campos usados no
HTML sejam iguais aos campos das tabelas.

Os campos localizados e mapeados ficam disponveis e uma mensagem mostrada


solicitando a confirmao ou o cancelamento deste procedimento.

HTML MAPPING

Para os campos que devem ser selecionados manualmente, basta selecionar o campo
desejado e clicar no boto MAP FIELD. Por exemplo, caso o campo CUSTNUM estiver
selecionado, ao clicar nessa opo, a janela FIELD SELECTOR aparece escolher qual campo
de qual tabela e de qual banco de dados ser feito o mapeamento.

Aps o mapeamento, a janela do Wizard indica de onde o campo foi mapeado.

Por fim o programa deve ser salvo e compilado para poder ser executado.

HTML MAPPING

Aps salvar o programa, o arquivo OFF criado automaticamente, onde gravado o tipo do
campo e a localizao de cada objeto no HTML. O arquivo .OFF criado com o mesmo nome
do arquivo salvo pelo HTML e WebSpeed.

Ao ser executado, o HTML mapeado usa o arquivo offset para determinar onde devem ser
inseridos os valores dos dados no HTML que gerado. Os nmeros no final de cada linha
indicam onde o campo inicia e termina do form. Entretanto, qualquer alterao no layout do
HTML, ocasionar a necessidade de criar novamente o arquivo de OFFSET. Isto pode ser feito
alterando o prprio arquivo .OFF ou criando novamente o arquivo pelo HTML Mapping Wizard
ou ainda, abrindo o arquivo no AppBuilder.

HTML MAPPING

No programa criado pelo HTML Mapping, existe uma procedure chamada htmOffSets. Esta
procedure responsvel por criar a associao entre os campos do form do HTML e os
campos do banco de dados.

Procedure PROCESS-WEB-REQUEST
Apenas associar o HTML aos campos do banco de dados no suficiente. importante
identificar o ponto onde o comando FIND usado para localizar os registros a serem
pesquisados. Porm, ao usar o HTML Mapping Wizard, a query criada adicionada como uma
OVERRIDE para a procedure findRecords.
A procedure PROCESS-WEB-REQUEST executa diversas procedures para controlar o fluxo de
informaes entre o Client e o objeto WEB e entre o objeto WEB e o fonte dos dados, seja esse
o banco de dados ou uma SmartDataObjects. As procedures ASSIGNFIELDS,
DISPLAYFIELDS e outras podem ser sobrepostas (OVERRIDE) por locais, podendo
customizar o comportamento padro destas procedures. O agente do WebSpeed primeiro
verificar pelas procedures locais e somente depois, se executado, pesquisar pelas Super
Procedures. Alm disso, as seqncias dos processos dependem do form do HTML, isto ,
dependem dos mtodos GET e POST. Quando a requisio vem do cliente pelo GET,
adicionada a URL do objeto WEB. Inicialmente o GET faz uma requisio e retorna um form em
branco. O POST envia os dados para o objeto WEB, onde normalmente usado aps um GET.
Para localizar os registros escritos no campo de CustNum e selecionados pelo boto Localizar,
necessrio colocar o comando FIND na procedure PROCESS-WEB-REQUEST. Entretanto,
se torna necessrio comentar a execuo da procedure findRecords.

HTML MAPPING

O valor do campo de CustNum a ser pesquisado, localizado pelo atributo SCREEN-VALUE e


ainda deve-se especificar em qual frame est. Para identificar a frame, usada a notao IN
FRAME {&FRAME-NAME}. Como no 4GL, o SCREEN-VALUE deve ser tratado como uma
varivel caracter, independente do tipo da varivel usada. Sendo assim, qualquer tratamento
da varivel deve ser feito usando funes para converter para o tipo correto, como por
exemplo, INTEGER, DECIMAL, DATE e outros. Desta forma, o valor de CustNum localizado
na rea de memria RECORD-BUFFER. Este buffer do objeto WEB onde os elementos do
HTML esto visveis. O uso das propriedades dos objetos definidos no HTML, como FILL-INs,
feito como no 4GL, usando o : para separar o objeto (WIDGET) da propriedade.

Ao executar o programa inicialmente, o primeiro registro de Customer ser mostrado. Aps


digitar um novo cdigo, os dados desse novo registro sero mostrados.

HTML MAPPING

Outra maneira de escrever o comando FIND utilizando a funo GET-VALUE que retorna o
valor da pgina WEB. Para o uso desta funo, no necessrio referenciar ao Buffer.

HTML MAPPING

7.1.2. Novas Funcionalidades no HTML Mapping


Novas funcionalidades podem ser adicionadas ao HTML como pesquisar outros registros ou
gravar informaes alteradas no form.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<META NAME="SQLWorks" CONTENT="SQLWorks Consultoria Ltda">
<TITLE>Localizar Customer</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<H1>Detalhes de Customer</H1>
<FORM ACTION="pagina110.w" METHOD="POST">
<P>
Entre com Customer: <INPUT NAME="CustNum" SIZE="5">
<INPUT TYPE="SUBMIT" NAME="Button" VALUE="Localizar"><BR><BR>
Nome: <INPUT NAME="Name" SIZE="20">
--------Telefone: <INPUT NAME="Phone" SIZE="20"><BR><BR>
Endereco 1: <INPUT NAME="Address" SIZE="20"><BR>
Endereco 2: <INPUT NAME="Address2" SIZE="20"><BR><BR>
Cidade: <INPUT NAME="City" SIZE="12">
---Estado: <INPUT NAME="State" SIZE="20">
---Cep: <INPUT NAME="PostalCode" SIZE="10"><BR><BR>
Comentarios: <TEXTAREA NAME="Comments" ROWS="2" COLS="30"></TEXTAREA><BR><BR>
<INPUT TYPE="SUBMIT" NAME="Button Value" VALUE="Primeiro">
<INPUT TYPE="SUBMIT" NAME="Button Value" VALUE="Anterior">
<INPUT TYPE="SUBMIT" NAME="Button Value" VALUE="Proximo">
<INPUT TYPE="SUBMIT" NAME="Button Value" VALUE="Ultimo">
<INPUT TYPE="SUBMIT" NAME="Button Value" VALUE="Salvar">
</P>
</FORM>
</BODY>
</HTML>

Visualmente, o programa adicionar alguns botes para que os registros sejam navegados e
alterados.

HTML MAPPING

Entretanto, a procedure PROCESS-WEB-REQUEST dever sempre pesquisar qual foi o boto


selecionado para que a funo correta seja disparada. Para isso, inicialmente uma varivel do
tipo caracter deve ser definida para que possa auxiliar nesse tratamento, ou usar o comando
CASE para identificar os eventos usados.

HTML MAPPING

Identificando o Evento Gerado


A funo GET-VALUE busca o nome do boto acessado. Este valor ao ser atualizado na
varivel criada, possibilita que a varivel seja usada para especificar qual a funo desejada.
Mas para isso, todos os botes devem ter o mesmo nome, alterando apenas os seus valores.
No exemplo usado, Button Value o nome de todos os objetos que fazem o SUBMIT e os
valores so os Localizar, Primeiro, Anterior, Prximo, ltimo e Salvar. Estas palavras so os
valores lidos dos botes para serem usados pelos comandos de pesquisa de registro (FIND).

HTML MAPPING

Localizando as Novas Leituras de Registros


Entretanto alguns cuidados devem ser tomados. No caso da pesquisa dos registros anteriores
e aos prximos ao atual, importante lembrar que todo evento disparado estar executando
novamente o programa. Desta forma, aps uma leitura de registro, o Record Buffer estar
sempre indisponvel. Ao pesquisar os anteriores ou prximos, ser mostrado sempre o primeiro
registro. Para evitar essa situao, uma sada seria reler o registro que est visvel na form da
pgina WEB e s ento pesquisar pelos prximos ou anteriores.

HTML MAPPING

Alterao de Registros
O processo para salvar o registro alterado no form da pgina WEB, depender da releitura do
registro usando o LOCK adequado (EXCLUSIVE-LOCK), verificar se existe algum usurio
travando esse registro, usando a funo LOCKED e por fim, verificando se o usurio est ou
no disponvel.

HTML MAPPING

HTML MAPPING

7.1.3. HTML Mapping usando SDO


O mapeando dos campos usados no HTML com o cdigo Progress, tambm podem ser feito
atravs de SmartDataObjects (SDO). A diferena bsica que o mapeamento deve ser feito
entre o HTML e a SDO e no mais a tabela do banco de dados.
O processo para mapear os campos do HTML com a SDO inicialmente a mesma do
mapeamento com campos de tabelas do banco de dados. Primeiramente importante
desenhar o HTML da aplicao.

Aps a criao do HTML e da SDO, a template a ser usada a HTML Mapping. Esta template
solicitar o nome do arquivo HTML que ser usado. Este HTML ter os campos que sero
mapeados.

HTML MAPPING

Aps selecionar o HTML a ser usado, importante referenciar qual a SDO a ser usada.
importante ressaltar que a SDO deve ter sido criada anteriormente.

Aps selecionar o nome da SDO a ser usada, ser mostrada na janela do HTML Mapping
Wizard os campos existentes no HTML que podem ser mapeados nos campos existentes na
SDO.

HTML MAPPING

Entretanto, bom ressaltar que nem todos os campos do HTML so obrigados a existir na
SDO e nem todos os campos da SDO so obrigados a existir no HTML. Apenas os campos
que so coincidentes sero mapeados.

No exemplo proposto, apenas 8 campos, os que foram definidos no HTML, sero mapeados
com a SDO ao clicar no boto Automap Fields.

HTML MAPPING

Aps acompanhar o Wizard desta template, o programa final criado com os mapeamentos j
desenvolvidos.

Apenas os campos invisveis (ou escondidos) e os campos que no encontraram um campo


relacionado no foram mapeados.
O campo CusRowid mantm o ROWID do registro corrente para auxiliar no processo de
navegao dos registros, estabelecendo uma comunicao entre o HTML e o agente do
WebSpeed. O campo AddMode indica se o tratamento realizado foi de navegao ou
atualizao do banco de dados.
Para o funcionamento do programa, alguns tratamentos sero necessrios.
Criao da TRIGGER para tratar o campo CusRowid
A procedure setCurrentRowids recebe o valor do campo CusRowid, dizendo ao agente do
WebSpeed que registro da tabela est sendo referenciado.

HTML MAPPING

Criar uma procedure para responder ao campo AddMode


Para isso, foi criado como OVERRIDE da super procedure inputFields e customizada para
identificar se um novo registro ou no.

HTML MAPPING

Criar uma procedure para gerenciar os campos no mapeados


A procedure usada a sobre-carga (Override) da procedure outputFields. Esta procedure ir
setar o valor do campo no nomeado cusrowid com o registro corrente.

HTML MAPPING

Modificar a procedure Process-Web-Request para responder aos eventos


necessrio criar os tratamentos para identificar qual boto foi acessado.

O resultado final um programa com maior complexidade e diversas opes alm da


navegao entre e registros e salvar o registro corrente alterado.

HTML MAPPING

GERENCIANDO SADA COM DISPLAY

8. Gerenciando Sada com DISPLAY


O WebSpeed prove suporte para WEB formatando no SpeedScript o comando DISPLAY. Este
suporte permite mais do formato automtico de sada do comando DISPLAY para ser refletido
na pgina WEB. possvel ainda controlar como esta formatao espelhada no HTML.

8.1. TRABALHANDO COM A SADA DISPLAY


O comando DISPLAY no SpeedScript fornece uma formatao de sada automtica apropriado
para um relatrio ou terminal. O WebSpeed gerencia essa sada em modos diferentes,
dependendo de como seu uso, podendo usar mecanismos para alterar a sada padro.
Para usar o comando DISPLAY, deve-se decidir por duas situaes:
Onde ser feita a sada.
Como ser a aparncia da sada.

8.1.1. Sada Direta do DISPLAY


Como todos comandos de sada do SpeedScript, o comando DISPLAY sempre tem sua sada
direcionada para uma stream em particular. No WebSpeed, esta stream de sada deve ser
tambm direcionada para o dispositivo WEB (WEB Server). O WebSpeed possui dois meios
para direcionar a sada do DISPLAY para um stream:
Usar o stream de sada do WebSpeed definido para o SpeedScript.
Definir e usar uma nova stream de sada do SpeedScript.
Pode ser melhor usar o stream de sada padro para manter um melhor gerenciamento de
sada para a pgina WEB. O comando PUT usa o stream de sada padro do WebSpeed pela
diretiva {&OUT}. Cada stream de sada tem sua prpria rea de gerenciamento de memria
(BUFFER), por isso, caso haja necessidade de possuir mais de uma sada para uma nica
requisio WEB, a atual seqncia de sada para a pgina WEB pode ser impraticvel, pois
deve ter especificado para cada comando de sada do objeto WEB a stream desejada.
Usando o Stream de Sada Definida para o WebSpeed
O WebSpeed possui duas definies de preprocessadores no SpeedScript para auxiliar no uso
da stream de sada:
&GLOBAL-DEFINE WEBSTREAM STREAM WebStream
&GLOBAL-DEFINE DISPLAY DISPLAY {&WEBSTREAM}
As
definies
destes
preprocessadores
esto
na
include
instalaoprogress/src/web/method/cgidefs.i usada pelos objetos WEB. Isto , os dois comandos
DISPLAY no exemplo seguinte acarretam no mesmo resultado:

GERENCIANDO SADA COM DISPLAY

O preprocessador {&OUT} manda gerar um salto de linha no HTML resultante.


O uso de uma das formas garante que os comandos DISPLAY que geram a pgina WEB de
sada correspondem aos pontos onde o cdigo aparece no objeto WEB.
Definindo e Usando uma Nova Stream de Sada
Para definir e usar uma nova stream de sada, o WebSpeed possui dois comandos:
Comando DEFINE STREAM <nome da stream> Define a Stream
Comando OUTPUT TO com a opo WEB Abre e direciona uma stream especfica
para o servidor WEB.
Se nenhum stream for usado no comando OUTPUT TO, o WebSpeed usa o stream no
nomeado padro para enviar os dados para a sada WEB. O exemplo seguinte define uma
nova stream e a direciona para o WEB:

GERENCIANDO SADA COM DISPLAY

Outra forma de abrir uma stream no nomeada padro direcionando para a WEB:

8.1.2. Formatando a Sada com DISPLAY


Normalmente, a sada gerada pelo DISPLAY formatada usando frames do SpeedScript. No
existem frames HTML, mas so estruturas lgicas mantidas pelo SpeedScript para gerenciar as
sadas. Existem diversos tipos de frames no SpeedScript que podem ser usados como stream

GERENCIANDO SADA COM DISPLAY

de sada para a WEB, podendo ser organizada como stream multi-frames de pginas. Stream
de pginas no so pginas WEB, mas sesses lgicas da pgina WEB contendo um ou mais
frames SpeedScript.
Os frames SpeedScript e as pginas com multi-frame Stream so estruturas que o WebSpeed
usa para formar uma nica pgina WEB para uma nica requisio. As frames SpeedScript no
retornam simplesmente sucessivas pginas WEB individuais, tais como aparecerem muitos
conjuntos de resultados na pesquisa WEB, elas provem um meio de dividir e estruturar uma
nica pgina WEB usando o comando DISPLAY e outros comandos SpeedScript.
O conceito de Stream aplicado tanto para o comando DISPLAY como para o comando PUT
para indicar a sada dos dados. Entretanto, apenas o comando DISPLAY realiza o tratamento
de frame no SpeedScripts.
possvel formatar o comando de sada DISPLAY usando dois meios:
Opes de pginas do comando OUTPUT TO WEB para gerar pginas com mltiplas
frames.
Atributos HTML no contexto WEB especificando o HTML para suportar ou modificar o
formato das frames no SpeedScript e nas pginas.
Opes de Pginas no Comando OUTPUT TO WEB
PAGED: Gera uma pgina de sada WEB com 56 linhas no Stream.
PAGE-SIZE <Nmero de Linhas>: Gera uma pgina de sada com o nmero de linhas
especificado no comando para o frame.
Para abrir uma Stream de sada no nomeada com 25 linhas, necessrio fazer:
OUTPUT TO WEB PAGE-SIZE 25.
Cada Stream contm a seguinte sada ordenada e organizada em uma das trs sesses, mas
todas com um nmero de linhas especificadas para a Stream:
1 Qualquer contedo de um frame PAGE-TOP no SpeedScript ativada por um Stream de
OUTPUT corrente. Caso contrrio, o Stream comea com a segunda sesso.
2 Qualquer outro comando de sada, tipo DISPLAY ou PUT para o Stream de sada corrente.
Se a sada de DISPLAY para o frame do tipo DOWN do SpeedScript, os cabealhos com as
colunas podem ser impressos nos seguintes casos:
No incio da interao do bloco.
No incio do Stream da pgina ou imediatamente depois de qualquer sada do frame
PAGE-TOP.
Se a sada do DISPLAY para o frame do SpeedScript for diferente de um DOWN frame, todo o
contedo de um frame especfico mostrado para cada comando DISPLAY.
Toda sada na segunda parte do Stream continua at que o nmero de linha indicada inicie
qualquer outra frame PAGE-BOTTOM ativa ou depois da ltima linha do Stream. O que vier
primeiro. Se o atributo PAGE-BUTTOM do frame de sada estiver ativado, o Stream continua
at a terceira sesso. Caso contrrio, a Stream est completa.
3 Qualquer contedo de um frame do SpeedScript ativa com atributo PAGE-BOTTOM para o
Stream de sada corrente at que a pgina esteja completa.
O uso do comando DISPLAY ativa as frames SpeedScript com PAGE-TOP e PAGE-BOTTOM,
mas no mostram de imediato a frame, mas a deixa preparada para as sadas no ponto

GERENCIANDO SADA COM DISPLAY

apropriado na Stream. O comando PUT, normalmente utilizado pelo preprocessador {&OUT},


pode realizar sada de dados na segunda sesso do Stream. Mas no faria parte de nenhum
frame do SpeedScript, que so usadas apenas no comando DISPLAY.
Atributos HTML do handle do WEB-CONTEXT
O handle do WEB-CONTEXT possui um conjunto de atributos para manipular a formatao da
sada na pgina WEB. Cada atributo uma string caracter que contm HTML usados para
adicionar partes especficas do frame do SpeedScript e sadas para a pgina. Qualquer
alterao feita em atributos ser observada apenas na prxima requisio da pgina WEB.
Cada requisio ocasiona no Agente a alterao dos valores dos atributos para os valores
iniciais. Isto ocorre quando os objetos WEB so Stateless e State-Persistent.
Atributo
(Localizao para Sada)
HTML-END-OF-LINE
(Fim de linha)

HTML-FRAME-BEGIN
(Antes do Frame
SpeedScript)

do

HTML-FRAME-END
(Depois do Frame
SpeedScript)

do

HTML-HEADER-BEGIN
(Antes do cabealho de
colunas do frame do
SpeedScript )
HTML-HEADER-END
(Depois do cabealho de
colunas do frame do
SeepScript)
HTML-TITLE-BEGIN
(Antes do ttulo do frame
do SpeedScript)
HTML-TITLE-END
(Depois do ttulo do frame
do SpeedScript)
HTML-END-OF-PAGE
(Entre as Streams)

Descrio
Os caracteres padres para indicar uma nova linha so ~n ou
/n. Ainda possvel setar uma nova linha usando a tag <BR>.
Uma nova linha pode ser inserida a cada interao dos registros
em um frame do tipo DOWN.
O padro a tag <PRE>, mas se for alterado para outro, o
mesmo deve ser feito no HTML-FRAME-END.
Deve ser colocado apenas antes dos registros da interao
corrente do frame (DOWN) e no no cabealho das colunas. Pode
ser aplicado para qualquer SIDE-LABELS mostrada no frame,
sendo ou no um frame do tipo DOWN.
O padro a tag </PRE>, mas se o HTML-FRAME-BEGIN for
alterado, este tambm deve ser alterado para o mesmo.
Deve ser colocado no final da interao corrente dos registros do
frame do tipo DOWN.
O padro a tag <PRE>, mas se for alterado para outro, o
mesmo deve ser feito no HTML-HEADER-END.
Deve ser colocado no incio da sesso de cabealhos das colunas
do frame do tipo DOWN.
O padro a tag </PRE>, mas se o HTML-HEADER-BEGIN for
alterado, este tambm deve ser alterado para o mesmo.
Deve ser colocado no fim da sesso de cabealhos das colunas
do frame do tipo DOWN.
O padro estar sem texto de ttulo. Se este valor for alterado,
deve-se alterar o valor de HTML-TITLE-END.
Deve ser colocada antes do valor do ttulo do frame. Pode-se
setar atributos como cor e espessura para melhorar a leitura.
O padro estar sem texto, mas se o HTML-TITLE-BEGIN for
alterado, este tambm deve ser alterado para o mesmo.
Deve ser colocada aps o texto do ttulo do frame.
O padro <HR>. Deve ser colocada entre as Streams para
visualizar a quebra das sesses causadas pelas opes PAGED e
PAGE-SIZE to comando OUTPUT TO WEB. No afetando o
contador de linhas de cada Stream.

8.2. ALTERANDO O FORMATO PADRO DE SADA


possvel alterar o formato padro de sada tanto para a definio de sada do Stream do
WebSpeed, quanto para os atributos do HTML do handle do WEB-CONTEXT.

GERENCIANDO SADA COM DISPLAY

8.2.1. Setando um Padro para {&WEBSTREAM}


O WebSpeed define como sada padro para WEB ({&WEBSTREAM}) como uma Stream sem
paginao. Entretanto, isso pode ser alterado ao modificar a definio do WebSpeed em
qualquer ponto do objeto WEB usando o comando OUTPUT CLOSE e o comando OUTPUT
TO WEB com opes para paginao.
OUTPUT {&WEBSTREAM} CLOSE.
OUTPUT {&WEBSTREAM} TO WEB PAGE-SIZE 25.
.
.
.
OUTPUT {&WEBSTREAM} CLOSE.
OUTPUT {&WEBSTREAM} TO WEB PAGE-SIZE 10.
.
.
.
OUTPUT {&WEBSTREAM} CLOSE.
OUTPUT {&WEBSTREAM} TO WEB.
Neste exemplo o Stream alterado diversas vezes no objeto WEB. Primeiro para 25 linhas,
depois para 10 linhas e por ltimo sem paginao.

8.2.2. Setando Atributos Padres no HTML


possvel alterar os valores iniciais padres para todos os atributos HTML do handle do WEBCONTEXT. Para isto, necessrio criar um arquivo texto no PROPATH com o nome
DISPLAY.DAT. Neste arquivo deve-se especificar a nova definio HTML para um ou todos os
atributos. Qualquer definio que estiver nesse arquivo ir sobrepor o padro existente no
WebSpeed sendo este padro fixo ou na requisio de cada servio na WEB.
Definindo Atributos
Existem regras bsicas para definio dos atributos no arquivo DISPLAY.DAT:
Qualquer linha iniciada com o sinal # um comentrio. Para escrever em uma mesma
linha uma informao adicional, necessrio indicar que essa continuao um
comentrio.
O primeiro caracter da primeira linha de uma definio, se no for comentrio, deve ser
um delimitador.
{Delimitador} {Atributo HTML} {Delimitador} [#]
[Definio do HTML] {Delimitador}
Delimitador
o primeiro caracter da primeira linha de cada definio, podendo ser especificado um
caracter diferente para cada definio de atributo.
Atributo HTML
Nome do atributo do WEB-CONTEXT que est sendo definido.
#

GERENCIANDO SADA COM DISPLAY

Apesar de opcional, permite que a definio do atributo seja feita na linha seguinte sem
considerar que seja uma nova linha, auxiliando na leitura do arquivo.
Definio do HTML
A definio inicia com o primeiro caracter depois do segundo delimitador de um mesmo atributo
HTML, a menos que seja iniciado com #. Caso existe o comentrio, a definio inicia com o
primeiro caracter da prxima linha. A definio pode continuar tantas linhas quantas desejadas,
at o terceiro delimitador que o indicativo da finalizao da definio do atributo. Caso
nenhum caracter seja colocado entre o segundo e o terceiro delimitador, a definio um valor
nulo.
Por exemplo:
# Exemplo usando comentrios no segundo delimitador
:HTML-FRAME-BEGIN:#
<FONT COLOR=BLUE>
<PRE>:
# Na prxima definio, o delimitador ser alterado de : para +
+HTML-FRAME-END+#
</PRE>
</FONT>+
Observe como os atributos HTML-FRAME-BEGIN e HTML-FRAME-END trocam a ordem das
tags de incio e fim seu perfeito funcionamento na pgina WEB.
No caso de uma definio de caracter nulo, fica:
:HTML-END-OF-LINE::
importante ressaltar que aps alterar ou criar o arquivo DISPLAY.DAT, necessrio reiniciar
o WebSpeed Transaction Server para que este arquivo tenha efeito.

CONTROLANDO TRANSAES WEBSPEED

9. Controlando Transaes WebSpeed


As transaes no WebSpeed possuem os mesmos conceitos de transaes no Progress 4GL.
importante entender o conceito no WebSpeed por causa do uso de pginas, pois a cada
execuo de pgina, basicamente uma transao ser criada e finalizada.

9.1. ESTADOS NO WEBSPEED


As transaes WEB so naturalmente STATELESS, isto , no existe conexo entre o servidor
WEB e o Client enquanto uma pgina preenchida. Sendo assim, o servidor WEB no mantm
nenhuma informao do Client em uma prxima referncia. Quando o resultado de um submit
de uma pgina mostrado no WEB browser, a transao j estar encerrada.
Entretanto, pode ser necessrio manter a transao ativa entre diversas pginas, mas como
esse no o procedimento padro, tem que ser tratado manualmente. Para estes casos existe
o STATE-PASSING, que armazena as informaes das transaes no Client e o STATEPERSISTENT que mantm a conexo entre o Client e o Agente WebSpeed por um perodo de
tempo pr-determinado.

9.1.1. Estados dos Objetos WEB


Existem dois tipos de estados que podem ser aplicados aos objetos WEB:
Stateless
State-aware
Objetos WEB Stateless so executados e destrudos em uma simples requisio WEB. O
Agente do WebSpeed que atende a esse objeto no mantm o contexto da situao atual para
uma prxima execuo do objeto.
Objetos WEB State-aware mantm o contexto executando persistentemente sobre um Agente
do WebSpeed locado. Um Agente locado fica dedicado para as requisies do Client
(Browser), aguardando respostas apenas deste Client at que o tempo determinado para timeout passe.
Nos 3 tipos de objetos WEB, apenas o CGI Wrapper e o HTML-Mapping podem ser objetos
WEB State-aware. O Embedded SpeedScript pode executar como Stateless em um agente
locado, mas o SpeedScript no pode locar ele mesmo o Agente. necessrio usar mtodos e
estruturas para interagir com o programa de controle do Agente.

9.1.2. Aplicaes WebSpeed usando os Estados


Basicamente 3 tipos de aplicaes podem ser criados usando os estados Stateless e Stateaware:
Stateless
State-passing
State-persistent

CONTROLANDO TRANSAES WEBSPEED

Aplicaes WebSpeed Stateless so compostos inteiramente por objetos WEB Stateless e


arquivos estticos, sendo que nenhuma informao mantida entre requisies de novas
pginas.
Aplicaes WebSpeed State-passing tambm so compostas inteiramente de objetos WEB
Stateless e arquivos estticos, entretanto, o contexto da informao passada para o Agente
WebSpeed pelo Client atravs de query strings pela URL, campos HTML e Cookies.
Aplicaes WebSpeed State-persistent so compostos de um ou mais objetos WEB stateaware. O Agente do WebSpeed locado para o Browser por um perodo especificado,
mantendo o contexto entre as requisies. Essas aplicaes so chamadas de Transaes
WebSpeed ou transaes State-persistent.

9.1.3. Vantagens e Desvantagens do State-persistent


A aplicao WebSpeed State-persistent possibilita:
Uma transao simples no banco de dados que abrange diversas requisies de
pginas, possibilitando desfazer completamente a transao (roll back) em caso de
erro.
Minimiza a quantidade de dados necessrios que devem ser passados de uma
requisio para outra.
Minimiza o acesso ao banco de dados para cada requisio, evitando ficar reabrindo as
tabelas.
Entretanto, o tratamento de transaes o conceito bsico do Progress.
O Agente fica locado at o fim da transao.
Um ou mais registros de uma ou mais tabelas ficam locados at o fim da transao.

9.2. ENTENDENDO O CONTROLE DE TRANSAO NO


WEBSPEED
A transao WebSpeed (State-persistent) permite manter ativo o contexto em um nico Agente
WebSpeed entre requisies, locando este Agente para um Client WEB. Para suportar as
transaes, o WebSpeed usa um programa para controlar o Agente. Este programa executa
qualquer objeto WEB que esteja especificado no URL para uma requisio. Feito isso,
verificado o status do objeto WEB para qualquer transao ativa no WebSpeed, travando o
Agente do objeto WEB que inicia a transao WebSpeed e destravando o Agente em qualquer
objeto WEB que termina a transao WebSpeed.
Para travar um agente temporariamente para um browser em particular,iniciando a transao
WebSpeed, necessrio executar a funo setWebState, antes da sada do cabealho HTTP.
Esta procedure realiza 2 funes bsicas:
Setar os cookies que permitem o Broker WebSpeed identificar o browser WEB, o
Agente WebSpeed e o objeto WEB que esto na transao. Setando o cookie tambm
garante que qualquer prxima requisio WebSpeed do browser usar o mesmo
Agente WebSpeed.
Um time-out em minutos setado para invocar um objeto WEB state-aware. Este
tempo o mximo que o usurio tem entre a requisio de transao subseqente
antes da transao terminar automaticamente. O Agente preso mantm esse tempo
para todos objetos WEB state-aware que so executados nessa transao corrente. O

CONTROLANDO TRANSAES WEBSPEED

cliente WEB que est no contexto da transao pode fazer outras requisies WEB,
incluindo requisies que usam outros Agentes. Entretanto, o tempo na transao
continua contando enquanto o browser est realizando outras requisies. O tempo
pode terminar caso o usurio no continue na transao que estava realizando as
alteraes.
Enquanto o Agente estiver atendendo as requisies para uma transao WebSpeed,
requisies feitas para a mesma URL, por outros clientes WEB, no podem ser servidos por
este Agente at a transao corrente terminar. O Agente preso continua servindo ambos
requisies state-aware e stateless da transao do cliente.

9.2.1. Como Fazer um Objeto Web State-aware


Basicamente, deve-se executar a funo setWebState para fazer um objeto state-aware ou
para cancelar uma condio state-aware:
SetWebState (time-out).
Onde o time-out:
Nmero inteiro que indica o nmero de minutos que o objeto WEB permanecer
persistente, quando maior que zero.
Quando o valor zero, o cookie do objeto WEB eliminado e o objeto volta a ser
stateless.
A funo setWebState deve ser executada antes da sada do cabealho HTTP e tambm antes
de qualquer funo de cookie ser chamada.

CONTROLANDO TRANSAES WEBSPEED

9.2.2. Objetos WEB no Contexto de Stateless e Statepersistent

Na figura apresentada, o objeto WEB X state-aware enquanto o Y stateless. Na parte


superior da figura, o objeto WEB Y executado dentro do contexto de uma transao
WebSpeed. O objeto WEB Y ainda stateless mesmo executado em um Agente locado porque
no possui um tempo de time-out para ele mesmo na transao. Mesmo assim, pode acessar
os dados do contexto estabelecidos pelo objeto WEB X, especialmente se o objeto WEB Y
executar uma procedure customizada do objeto WEB X que retorna dados do contexto da
transao. Normalmente, todos objetos WEB no Agente locado participam da mesma
transao WebSpeed, independente de serem stateless ou state-aware.
Se o cliente WEB fizer uma requisio para o objeto WEB Y, podendo ser atravs de um
Messenger e Broker de um WebSpeed diferente, o objeto WEB Y ser executado como
stateless no Agente B, mas sem necessariamente um contexto de transao disponvel.

9.3. OBJETOS WEB PRIMRIOS E SECUNDRIOS


Como mostrado na figura do tpico anterior, enquanto possvel construir uma transao
WebSpeed com uma combinao de objetos WEB stateless e state-aware, gerenciar essas
requisies mltiplas devem ser cuidadosas. O problema est em que cada objeto WEB
sucessivamente usado necessita saber alguma coisa sobre o que ocorreu na requisio
anterior, porm, provavelmente no sabe o que o objeto WEB executou na ltima requisio.
possvel passar cookies adicionais ou usar o URL para transmitir essa informao, mas
estar disperdiando a vantagem da manuteno do contexto estabelecido pela transao
WebSpeed. Pode-se evitar o uso de um simples objeto WEB primrio para iniciar uma
transao WebSpeed. Ao invs disso, usar um objeto WEB secundrio para prover pginas
adicionais na transao, permitindo assim compartilhar dados com o objeto WEB primrio ou,
por outro lado, comunicar atravs de dados locais no objeto WEB primrio.
Um objeto WEB secundrio um objeto WEB executado de outro objeto WEB que j est
servindo uma requisio no Agente. evidente que existe apenas um nico objeto WEB

CONTROLANDO TRANSAES WEBSPEED

primrio que gerencia todas as requisies e inicializa as chamadas para todos os outros
objetos WEB secundrios na transao.
No possvel usar Embedded SpeedScript como objetos WEB primrios, porque no podem
explicitamente tornar-se state-aware. Entretanto, podem ser aplicaes state-persistent como
objetos WEB secundrios. Sendo assim, os objetos WEB primrios devem ser CGI Wrapper ou
HTML-Mapping.

9.3.1. Executando Objetos WEB Primrios e


Secundrios
O ponto principal para um objeto WEB secundrio ele gerar ou mapear uma pgina WEB,
onde o cliente WEB deve fazer a requisio da prxima transao voltar ao objeto WEB
primrio.
O objeto WEB primrio normalmente seta o tempo de time-out para a transao. Como os
objetos WEB primrio e secundrio respondem a requisio de um cliente, o time-out continua
a contagem. Este valor no reiniciado a menos que o objeto WEB primrio explicitamente o
resete, reexecutando o mtodo setWebState. importante perceber que todos os objetos WEB
secundrios so implicitamente state-aware em virtude do objeto WEB primrio ter iniciado este
procedimento.
O objeto WEB primrio normalmente gera o cabealho HTTP para a pgina WEB. Entretanto,
para o Embedded SpeedScript, o objeto WEB primrio deve executar o mtodo setWebState
para propagar o cookie de state-aware para a prxima requisio de servio executando
qualquer Embedded SpeedScript.
Na prxima figura mostrado o relacionamento entre o cliente WEB e um objeto WEB primrio
(Objeto WEB A), objetos secundrios (Objetos WEB X, Y e Z) e uma transao cclica em uma
transao WebSpeed state-persistent. Neste caso, o objeto WEB A, controlando os objetos
WEB secundrios, define as variveis compartilhadas que podem ser referenciadas pelos
objetos WEB X, Y e Z.

1 O browser (WEB Client) executa diretamente somente o objeto WEB primrio (Web Object
A). O cliente WEB pode fazer chamadas repetitivas para o objeto WEB primrio, at o fim da
transao.
2 O objeto WEB A pode:

CONTROLANDO TRANSAES WEBSPEED

Chamar qualquer objeto WEB secundrio (X, Y ou Z).


Retornar a pgina WEB para o cliente WEB. Qualquer link ou referncia de retorno
para a pgina WEB, volta ao objeto WEB primrio A.
3 O objeto WEB secundrio pode:
Chamar qualquer outro objeto WEB secundrio.
Chamar o objeto WEB primrio.
Retornar a pgina WEB para o cliente WEB. Qualquer link ou referncia de retorno
para a pgina WEB, volta ao objeto WEB primrio A.
Em qualquer ponto do objeto WEB A pode ser determinado que seu uso foi feito para destravar
o Agente e possivelmente enviar de volta para a pgina WEB dizendo que a transao foi
finalizada.

9.3.2. Objetos WEB State-aware e Persistence


Apesar da figura anterior possibilitar que o objeto WEB A possa ser executado diversas vezes,
isto pode no ser necessariamente o que ocorre.
Normalmente, a primeira vez que um objeto WEB state-aware executado, ele inicializado. O
ltimo passo da inicializao executar a procedure process-web-request e retornar para o
programa que o chamou para completar a execuo. Entretanto, o objeto WEB normalmente
permanece como suspenso, mas com o estado ativo e conhecido como PERSISTENCE. Neste
estado persistence, qualquer procedure desse objeto WEB, incluindo o process-web-request,
pode ser executado por qualquer outro objeto WEB.
Na prxima vez que o objeto WEB persistente atende uma requisio, somente a procedure
process-web-request executada, sem sua inicializao, e geralmente esta procedure no
interage ou trabalha recursivamente.
O objeto WEB primrio geralmente executa o secundrio como um objeto WEB stateless, que
no fica persistente depois da execuo. O normal enviar uma pgina WEB para mostrar que
nenhum POST de dados anteriores para o objeto WEB secundrio foi feito. Entretanto, a
pgina deve retornar para o objeto WEB primrio para atender algum outro objeto WEB
persistente na transao.

9.4. IMPLEMENTAO DO CONTROLE DE TRANSAO


Os objetos WEB podem ser customizados para controlar as transaes WebSpeed. Isso pode
ser feito fazendo:
Modificando a procedure outputHeader.
Modificando a procedure process-web-request.
Sobrescrevendo procedures e funes.
Modificando a lista de atributos.
Modificando a lista de campos do usurio.
Somando a esses componentes, o CGI Wrapper e o HTML-Mapping contem cdigos adicionais
que podem ser modificados usando o editor do AppBuilder.

CONTROLANDO TRANSAES WEBSPEED

9.4.1. Modificando a Procedure outputHeader


A procedure outputHeader o padro para fazer o objeto WEB state-aware. O gerenciamento
da transao similar tanto no HTML-Mapping e CGI Wrapper.
A template WebSpeed para esta procedure contm a chamada da funo output-content-type.
Essa funo necessria para a sada do cabealho padro MIME para a pgina WEB.
Nesta procedure, quando usado o template, existe um comentrio inicial que indica como usar
o setWebState (ou set-web-state) e o set-cookie para transformar o objeto WEB em stateaware.
A funo setWebState seta o estado da transao WebSpeed para o objeto WEB. No exemplo
a seguir, o objeto WEB chamado transformado em state-aware com um time-out de 5
minutos.
setWebState(5).
Set-cookie(cust-num:U, 23:U, TODAY + 1, ?, ?, ?, ?).
Output-content-type(text/html:U).
Para um objeto WEB ser state-aware, a funo setWebState cria cookies que identifica o
Agente WebSpeed e o objeto WEB. Passado o tempo estabelecido como time-out, os cookies
so destrudos.
A funo setWebState est localizada na super procedure admweb.p. O objeto WEB executa
essa super procedure persistentemente para possibilitar o acesso a diversos mtodos e
funes.
Para terminar o estado de state-persistent da transao do WebSpeed e destravar o Agente,
necessrio executar o setWebState com o tempo do time-out como zero.
Embora a funo setWebState cria automaticamente cookies que identificam o Agente do
WebSpeed e o objeto WEB, possvel criar cookies adicionais para passar outras informaes.
A funo set-cookie executada depois do setWebState permite gerar cookies adicionais,
podendo ser executada diversas vezes para definir todos os cookies necessrios.
No exemplo anterior, o cookie expira no prximo dia a meia-noite. O valor padro
representado por um valor desconhecido, indicado como interrogao (?).

9.4.2. Modificando a Procedure process-web-request


A procedure process-web-request o mtodo primrio para gerenciar as entradas de
requisies WEB e as sadas para a pgina WEB do objeto WEB. Para um objeto WEB stateaware, este a procedure onde o Agente controla as chamadas dos programas para gerenciar
as requisies destinadas ao objeto WEB.
As templates CGI Wrapper e HTML-Mapping possuem comentadas, dicas para gerenciar uma
requisio WEB genrica.
O CGI Wrapper contm para esta procedure a chamada necessria para a procedure
outputHeader e comandos de sada para uma pgina WEB bsica. Caso contrrio, o contedo
dessa procedure inteiramente dependente da aplicao.
O HTML-Mapping tambm contm para esta procedure a chamada da procedure outputHeader
e possui um padro completo para CGI GET e POST, requisitando o framework que gerencia

CONTROLANDO TRANSAES WEBSPEED

as requisies WEB. Este framework possui um mecanismo padro para mover os dados entre
as pginas mapeadas e o objeto WEB. Em ambos os casos, possvel modificar as verses do
process-web-request para a aplicao.

9.4.3. Sobrescrevendo Procedures e Funes


O WebSpeed possui mecanismos para customizar procedures e funes sem necessariamente
acessar o cdigo fonte original, apenas sobrescrevendo as procedures e funes existentes.
O processo de sobrescrever as procedures e funes fica mais fcil com o uso do Section
Editor no AppBuilder, pois trabalha-se diretamente com verses locais das procedures e
funes nos objetos WEB. As procedures e funes locais possuem as chamadas para as
verses oficiais, ou ainda podem alterar totalmente o cdigo sem chamar as originais. Este o
tratamento de Super Procedures, onde tratada a hierarquia e a reusabilidade dos cdigos
originais.
Neste processo de Super Procedure, quando uma procedure ou funo invocada,
primeiramente a verso local executada, caso exista. O cdigo antes da chamada da original
executado, executa-se a original e depois o cdigo aps o funcionamento padro. Caso a
local no seja encontrada, a procedure original executada diretamente. Essa verso original
est nas Super Procedures que so executadas persistentemente pelo Agente do WebSpeed.
Uma Super Procedure uma procedure externa executada de forma persistente. Estas Super
Procedures usam o modelo orientado a objetos para implementar e extender comportamentos
comuns para as aplicaes, podendo:
Definir um comportamento padro.
Executar o comportamento padro.
Sobrescrever o comportamento padro com uma verso localizada.
Tratar o comportamento padro com caractersticas anterior e posterior ao mesmo.
Sobrecarga e heranas mltiplas do comportamento das classes.

9.4.4. Modificando a Lista de Atributos


Uma lista de atributos define um conjunto de pares de Nomes/Valores aplicados para um objeto
WEB especfico executado no Agente.
O WebSpeed faz um uso intensivo da lista de atributos para cada objeto WEB para gravar
informaes crticas, como o estado da transao do objeto WEB. Para acessar os atributos,
existem os mtodos set-attribute-list e get-attribute.
A maioria dos acessos WebSpeed para essas listas escondida por outras procedures e
funes como por exemplo setWebState. Entretanto, possvel setar e recuperar atributos
especficos para o objeto WEB usando as procedures set-attribute-list e get-attribute.
aconselhvel no alterar os atributos de estado do objeto WEB ou time-out usando a
procedure set-attribute-list.

9.4.5. Modificando a Lista de Campos do Usurio

CONTROLANDO TRANSAES WEBSPEED

A lista de campos do usurio define um conjunto de pares de Nome/Valor para serem usados
na aplicao. A lista de campos do usurio fica disponvel para todos os objetos que esto
sendo executados no Agente.
A funcionalidade dos campos de usurios totalmente dependente da necessidade da
aplicao, como, por exemplo, passar parmetros entre objetos WEB que esto sendo
executados no mesmo Agente para uma mesma requisio WEB (ou transao WebSpeed, se
o Agente estiver locado).
Para criar e acessar explicitamente os campos de usurios, o WebSpeed possui as funes
set-user-field e get-user-field.

9.5. CONTROLE DE TRANSAO USANDO EMBEDDED


SPEEDSCRIPT
O Embedded SpeedScript possui uma estrutura simples para a execuo do WebSpeed, pois,
so basicamente arquivos HTML convertidos para objetos WEB. Sendo assim, no podem
executar a funo setWebState para ser eles mesmos state-aware. O Embedded SpeedScript
geralmente usado apenas como stateless ou objetos WEB secundrios em transaes
WebSpeed. Eles sempre so executados como no persistentes dentro e fora de uma
transao WebSpeed.
possvel definir um mtodo outputHeader nos arquivos Embedded SpeedScript para gerar a
sada dos cookies para a aplicao na gerao de uma pgina WEB. Entretanto, este
Embedded SpeedScript no pode, para ele mesmo, suportar a execuo da setWebState para
tornar o objeto WEB state-aware.

9.6. CONTROLE DE TRANSAO USANDO CGI


WRAPPER
O WebSpeed permite alterar o CGI Wrapper customizando os cdigos atravs do Section
Editor do AppBuilder.
O CGI Wrapper suporta todas as tcnicas para iniciar e gerenciar transaes WebSpeed. Alm
das procedures outputHeader e process-web-request, as sees padres do CGI Wrapper
contm:
DEFINITIONS: Neste ponto devem ser colocadas as definies de preprocessadores,
variveis e parmetros que estaro disponveis para todo o objeto WEB.
MAIN BLOCK: Nesta sesso, a linha principal do objeto WEB realiza a inicializao e
executa a process-web-request durante a execuo inicial e criao do objeto WEB.
Normalmente, no uma rea a ser modificada, a menos que seja para executar o
cdigo apenas uma nica vez quando o objeto WEB state-aware chamado. Para
realizar esse tipo de customizao, normalmente uma procedure local de inicializao.

9.7. CONTROLE DE TRANSAO USANDO HTMLMAPPING

CONTROLANDO TRANSAES WEBSPEED

O WebSpeed permite codificar o HTML-Mapping customizando como desejado sees do


cdigo usando o Section Editor do AppBuilder.
Junto com as procedures outputHeader e process-web-request, o cdigo padro do HTMLMapping inclui:
htmOffsets: Essa procedure associa automaticamente cada campo do formulrio
HTML com o objeto de campo correspondente no objeto WEB. Entretanto, essa
procedure apenas de referncia, isto , Read Only.
Definitions: Neste ponto devem ser colocadas as definies de preprocessadores,
variveis e parmetros que estaro disponveis para todo o objeto WEB.
Main Block: Nesta sesso, a linha principal do objeto WEB realiza a inicializao e
executa a process-web-request durante a execuo inicial e criao do objeto WEB.
Normalmente, no uma rea a ser modificada, a menos que seja para executar o
cdigo apenas uma nica vez quando o objeto WEB state-aware chamado.
Control handlers: Nesta procedure possvel sobrescrever os gerenciadores do
web.input e web.output para um campo de objeto especfico. Esta procedure aparece
apenas nos objetos WEB HTML-Mapping.
Mtodos ADM (ADM-Events): So procedures responsveis pelo comportamento
padro para o process-web-request do HTML-Mapping e de outras sees do HTMLMapping, podendo sobrescrever procedures padres como displayFields, assignFields
ou initialize.

9.7.1. Entendendo o process-web-request no HTMLMapping

O process-web-request a principal procedure do HTML-Mapping. A figura anterior mostra


como a verso padro do process-web-request do HTML-Mapping funciona em uma
requisio.
Este modelo padro pode aplicar se o objeto WEB acessado via URL de um browser ou
chamado diretamente de outro objeto WEB.
Cada caixa representa uma procedure, ao do banco de dados ou um de diversas procedures
que realizam o servio bsico de requisio.

CONTROLANDO TRANSAES WEBSPEED

outputHeader: Procedure responsvel pela sada do cabealho HTTP.


inputFields: Procedure responsvel para mover todos os valores dos elementos do
formulrio HTML recebidos em uma requisio para seus campos correspondentes no
objeto WEB. Estes campos so definidos inicialmente quando o objeto criado no
AppBuilder.
FIND/CREATE de registros: Este o ponto padro onde deve ser definida
localizao ou criao de um registro. Este registro possui dados para os campos de
objetos mapeados com os campos do banco de dados.
assignFields: Procedure que move os valores para atualizao dos campos do
formulrio para as variveis ou campos de tabelas correspondentes no objeto WEB.
displayFields: Procedure que move das variveis e campos de tabelas para campos
dos objetos do formulrio correspondentes.
enableFields: Procedure que torna alguns campos do formulrio habilitados para o
usurio da pgina WEB. O valor de qualquer campo desabilitado mapeado no HTML
como uma tag de <INPUT> do tipo TEXT, HIDDEN ou PASSWORD ser um simples
texto de sada no HTML e no retorna como entrada para a prxima requisio. Os
campos que aparecem como desabilitados no so atualizados pelo assignFields.
outputFields: Procedure que passa a pgina WEB para o WEB Server, consolidando
todos os valores de campos com a pgina WEB de acordo com as tags que so
mapeadas para o objeto WEB. O objeto WEB usa o arquivo de offset neste ponto para
interagir os dados dentro do arquivo HTML original que foi usado para gerar o HTMLMapping.

9.7.2. Modificando a Lgica de Requisio


A lgica padro da procedure process-web-request tem como ordem de execuo, testar a
varivel REQUEST_METHOD. Independente da customizao das procedures possvel
alterar o local das chamadas destas procedures na lgica, dependendo da aplicao. Pode-se
adicionar tambm outros testes para os valores dos botes de submit ou outros dados que so
retornados com cada requisio.
Normalmente, existe um GET quando o usurio usa um link ou entra com uma URL no objeto
WEB. Embora possvel criar um formulrio HTML que retorne outro GET, limitaes na
quantidade de dados que o browser pode retornar com o GET, torna a requisio com o POST
a mais indicada. Um GET passa dados como parte de uma URL, enquanto o POST passa
dados atravs da entrada padro do Agente.
Entretanto, como indicado nos comentrios da process-web-request, uma requisio com GET
possue outras finalidades. Por exemplo, se for desejado retornar uma pgina WEB diferente de
uma que j foi postada, o objeto WEB que gerencia o post tem que chamar outro objeto WEB
para ter a nova pgina. Isto feito depois de enderear o POST corrente e antes de iniciar o
retorno do formulrio corrente.
Mas, quando chamar um novo objeto WEB, pode ser desejvel que ele fosse chamado como
uma requisio CGI GET, devendo retornar a nova pgina como uma primeira vez. Para
simular uma requisio como GET, o WebSpeed permite atualizar a varivel
REQUEST_METHOD do objeto WEB para alterar o mtodo (neste caso de POST para GET)
antes de chamar um novo objeto WEB.
importante ficar atento para esta tcnica, pois pode no ser segura para todos os casos.
necessrio estar atento com o que pode acontecer com os dados passados com o POST atual.
Internamente, o WebSpeed trata um GET ou POST do mesmo modo. Isto , quando valores de
dados de entrada so recuperados de uma requisio, os dados so sempre verificados do
formulrio postado tanto no URL (recuperado da query string) e a entrada padro. possvel

CONTROLANDO TRANSAES WEBSPEED

alterar o mtodo de requisio do objeto WEB chamado para GET e ainda permitir o objeto
recuperar qualquer dado vindo de um POST anterior.
Ao alterar o mtodo de requisio de POST para GET para um objeto WEB chamado, o
desenvolvedor deve alterar o mtodo de requisio de volta para um POST quando o objeto
WEB retornar para o chamador.
Tambm possvel recuperar os dados independentemente do mtodo de requisio. Para isto
deve-se usar a funo get-value( ). Esta funo retorna o valor de qualquer item nomeado, se
veio de uma QUERY STRING ou entrada padro.
Como os objetos WEB no cuidam de onde suas entradas vm, necessrio construir a
aplicao WebSpeed baseando-se em lgicas de requisio nos valores retornados pela
funo get-value( ) e ignorar o mtodo inputFields inteiramente ou sobrescreve-lo.
A menos que seja desejado resetar o REQUEST_METHOD, ou se o objeto WEB secundrio
state-aware, possvel executar diretamente o objeto WEB secundrio.

9.7.3. Movendo os Dados Atravs do HTML-Mapping


Para auxiliar o entendimento do impacto da lgica padro no process-web-request e alguns
dos efeitos esperados da sobre-carga, a prxima figura mostra onde as procedures padres
movem os dados no objeto WEB.

Frame Buffer e Record Buffer


O Frame Buffer a rea de memria do objeto WEB para armazenar os dados recebidos
diretamente dos campos do formulrio do HTML ou que esto sendo preparados para a sada
de dados para a pgina WEB. Os dados so armazenados no formato caracter, pois so
compatveis com a aparncia da pgina WEB. Cada item armazenado em um objeto
equivalente ao elemento do formulrio do HTML. Deste modo, estes objetos so como janelas
dentro do Frame Buffer para cada item de dados acessados pelo objeto WEB.
No caso do SpeedScript, o Frame Buffer equivalente ao Screen Buffer do Progress 4GL. A
diferena que para o 4GL, cada objeto de campo no Screen Buffer suporta interao com o
teclado local e o monitor. Para o SpeedScript, cada campo no Frame Buffer uma rea
intermediria para mover os dados para e da WEB.
O Record Buffer a rea de memria para armazenar os valores dos campos de tabelas e
variveis que foram lidos do banco de dados e que devero ser gravados no banco de dados.

CONTROLANDO TRANSAES WEBSPEED

Cada item gravado no Record Buffer de acordo com o tipo de dado do SpeedScript que
definido por uma varivel correspondente ou campo de tabela.
Movimentao de Dados para o inputFields
Para os dados colocados nos campos do formulrio, no momento de uma requisio, o
inputField recupera os valores de todos os campos existentes no arquivo tagmap.dat, os
colocando nos seus campos correspondentes do Frame Buffer. O inputFields faz isso
executando o web.input padro definido para cada tipo do elemento do formulrio. Lembrando
ainda que o web.input pode ser customizado usando o Section Editor do AppBuilder.
Movimentao de Dados para o assignFields
Cada campo no Frame Buffer corresponde pelo nome a um elemento no HTML. Cada campo
tambm correspondente para o nome de varivel ou campo de tabela no Record Buffer. A
movimentao dos valores do Frame Buffer para o Record Buffer obedecendo o tipo de dados.
Se um campo de tabela no for selecionado, o AppBuilder pode definir uma varivel com um
nome similar ao nome do elemento correspondente no formulrio ou definido pelo prprio
desenvolvedor e setar o campo fonte no AppBuilder para o usurio.
importante ressaltar que o assignFields move apenas dados de campos do objeto que
possuem a propriedade ENABLE setada como YES, que o padro. Esta propriedade pode
ser alterada pelo AppBuilder.
Transaes Atualizadas
Em qualquer ponto que o Agente Transacional ou o objeto WEB atualiza a transao corrente
do banco de dados (ou subtransao), qualquer registro do banco de dados alterado durante a
transao ser gravado no banco de dados, incluindo registros alterados pelo assignFields ou
pelo SpeedScript diretamente.
Localizando Registros
Para uma requisio WEB, o retorno tpico de uma query do banco de dados de 1 registro (ou
um registro por tabela no JOIN) com os valores mapeados nos campos do objeto. Geralmente,
o comando FIND usado para executar a leitura do registro. Entretanto, pode ser necessrio
requerer outro arquivo de I/O ou clculos para fornecer os valores das variveis locais ou
campos dos usurios no objeto que tambm so mapeados para a requisio. Ainda possvel
recuperar registros de qualquer lugar, customizando as procedures locais ou sobrescrevendo
as ADM-Events.
Movimentao de Dados para o displayFields
O displayFields move os valores de variveis e campos do Record Buffer para o Frame Buffer,
convertendo todos os valores para caracter. possvel ainda trocar a opo de FORMAT do
banco de dados usando as janelas de propriedades no AppBuilder. O displayFields movimenta
somente dados para os campos que possuem a propriedade de DISPLAY como YES, que o
padro. Este atributo pode ser alterado nas janelas de propriedades do AppBuilder.
Efeitos do enableFields
O enableFields modifica o atributo SENSITIVE dos campos no Frame Buffer. Se esta
propriedade for setada como NO, os campos ficam visveis como TEXT e ficam incapacitados
de receber qualquer interao de entrada de dados por ao do web.output.
O enableFields somente habilita campos para entrada de dados que foram setado o ENABLE
como YES. Este atributo pode ser alterado nas janelas de propriedades do AppBuilder.

CONTROLANDO TRANSAES WEBSPEED

Movimentao de Dados para o outputFields


O outputFields realiza as tarefas principais requeridas para fornecer a pgina WEB para o WEB
Server. Inclusive combinando os dados do Frame Buffer dentro da pgina WEB mapeado. O
outputFields faz isso executando o web.output definido para cada elemento mapeado e
customizado que encontrado na pgina WEB de sada.
Se um campo padro no est habilitado para entrada e o elemento do formulrio
correspondente uma tag <INPUT> do tipo TEXT, HIDDEN ou PASSWORD, a procedure faz a
sada ser um valor TEXT no local do elemento no formulrio. Como o elemento no formulrio
facilmente eliminado e recolocado por um texto que pode nunca ser alterado pelo usurio ou
retornado como um valor na prxima requisio com o formulrio. Deste modo, a prxima
requisio da pgina WEB chega como se o elemento nunca tivesse existido e o web.input
correspondente nunca v qualquer entrada para ele. Para os outros tipos de elementos, como
RADIO-SET, o padro do web.input retornar qualquer dado que esteja no Frame Buffer, mas
nunca ser atualizado em uma varivel ou campo de tabela.
A propriedade de DISPLAY ativo para um campo no possui efeito no outputFields.Tudo o que
acontecer no Frame Buffer uma sada.
A sada para um elemento para um formulrio inteiramente responsabilidade do
desenvolvedor, principalmente se for definido seus prprios campos mapeados ou
sobrescrever o web.output padro. Por exemplo, deve-se interpretar um valor para um
elemento do formulrio, recolocando ou combinando sua sada com uma referncia HTML para
uma imagem, usando a tag <IMG>.
possvel habilitar e desabilitar campos para entrada de dados durante cada requisio, mas
somente se primeiramente definir o campo como habilitado para ser usado como entrada
usando as propriedades do AppBuilder. Feito isto, pode-se setar o atributo SENSITIVE do
campo, em qualquer ponto entre a execuo padro do enableFields e outputFields.

9.7.4. Criando as Definies


O cdigo exemplo a seguir mostra a rea de definies do Section Editor de um objeto WEB.
Neste exemplo, uma varivel caracter definida para representar a ao de um boto.
/*-----------------------------------------------------------------------Arquivo:
Descrio:
Autor:
------------------------------------------------------------------------*/
/*
This .W file was created with AppBuilder.
*/
/*----------------------------------------------------------------------*/
/* Create an unnamed pool to store all the widgets created
by this procedure. This is a good default which assures
that this procedure's triggers and internal procedures
will execute in this procedure's storage, and that proper
cleanup will occur on deletion of the procedure. */
CREATE WIDGET-POOL.
/* ***************************

Definitions

************************** */

/* Preprocessor Definitions ---

*/

/* Parameters Definitions ---

*/

/* Local Variable Definitions --*/


DEFINE VARIABLE vButton AS CHARACTER NO-UNDO. /* Submit button value */

CONTROLANDO TRANSAES WEBSPEED

9.7.5. Modificando o Main Block


O cdigo a seguir o exemplo do MAIN BLOCK executado no HTML-Mapping:
/* ************************

Main Code Block

************************* */

/* Standard Main Block that runs adm-create-objects, initializeObject


* and process-web-request.
* The bulk of the web processing is in the Procedure process-web-request
* elsewhere in this Web object.
*/
{src/web2/template/hmapmain.i}

A include hmapmain.i contm um cdigo padro que executado a cada momento que um
objeto WEB stateless executado e a primeira vez que um objeto state-aware executado:
/* The CLOSE event can be used from inside or outside the procedure to */
/* terminate it. */
ON CLOSE OF THIS-PROCEDURE
RUN destroy.
/* Now enable the interface and wait for the exit condition. */
/* (NOTE: handle ERROR and END-KEY so cleanup code will always fire. */
MAIN-BLOCK:
DO ON ERROR UNDO MAIN-BLOCK,
LEAVE MAIN-BLOCK
ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK
ON STOP UNDO MAIN-BLOCK,
LEAVE MAIN-BLOCK:
/* Load the HTM handles etc. */
RUN initialize.
/* Process the current web event. */
RUN process-web-request.
END.
/* Run the local/adm-destroy procedures, if the procedure is ending. */
IF NOT THIS-PROCEDURE:PERSISTENT THEN RUN destroy.

Este cdigo primeiramente registra uma chamada para a procedure DESTROY como uma
trigger de SpeedScript. (ON CLOSE do objeto WEB).
Cdigos iniciais para o fonte, podem ser melhores aproveitados em uma procedure de
INITIALIZE local do que no prprio MAIN BLOCK.
A procedure DESTROY original remove todos os traos do objeto WEB da memria.
Entretanto, possvel sobrescrever essa procedure para realizar qualquer outra atividade de
limpeza necessria antes do objeto WEB ser fechado definitivamente. Em aplicaes statepersistent isto mais comum para gerenciar uma finalizao mais recente de transaes de
banco de dados com mltiplas pginas.
A procedure de inicializao realiza um nmero de atualizao de dados que so necessrios
antes do objeto WEB ser executado. possvel sobrescrever este evento para adicionar
qualquer tarefa que deva ser executado apenas uma nica vez antes de executar o processweb-request.
Caso o cdigo seja inserido diretamente no MAIN BLOCK, antes ou depois da inicializao
ocorrer e executar o process-web-request bom lembrar que este cdigo executa apenas uma
nica vez para objetos WEB state-aware. Cada tempo adicional que o Agente Transacional ou
outro objeto WEB executa usando a procedure run-web-object, somente o process-web-request
executado por um objeto WEB at o time-out. Quando o time-out ocorrer, a procedure
DESTROY ser executada.

CONTROLANDO TRANSAES WEBSPEED

9.7.6. Customizando Campos no Control Handlers


O Control Handlers dos campos do objeto implementam a converso entre o HTML e os
campos dos objetos para cada elemento do formulrio e o tag customizado que mapeado no
objeto WEB. Este mapeamento definido pela combinao do HTML da pgina WEB e o
arquivo tagmap.dat usado na aplicao.
O cdigo a seguir mostra o arquivo tagmap.dat padro:
#Default data mappable fields
#
# Do not move the first line below from its position. The first line is
# the default field type for fields missing TYPE=.
input,,text,fill-in,web/support/webinput.p
input,,checkbox,toggle-box,web/support/webtog.p
input,,hidden,fill-in,web/support/webinput.p
input,,password,fill-in,web/support/webinput.p
input,,radio,radio-set,web/support/webradio.p
select,/select,,selection-list,web/support/weblist.p
textarea,/textarea,,editor,web/support/webedit.p
#Custom Tag that can be used to support HTML Tables and 3rd Party controls
!--WSTAG,,,fill-in,web/support/tagrun.p
#Custom Tag that can be used to notify an application to output messages
#messages that have queued up using the queue-message function
!--WSMSG,,,fill-in,web/support/webmsg.p

O arquivo tagmap.dat contm campos HTML definidos que especificam o tipo do elemento
HTML no formulrio e tags customizados usados por todos os objetos WEB em uma aplicao.
O WebSpeed possui um arquivo tagmap.dat padro que suporta elementos HTML no
formulrio comuns. possvel adicionar ou modificar estas definies de campos. A definio
padro inclui o elemento HTML no formulrio especificando com as tags <INPUT>,<SELECT>
e <TEXTAREA>.
Cada campo HTML possui uma definio por linha no arquivo tagmap.dat como mostrado na
sintaxe a seguir:
tag-name,[tag-encerramento],[tipo-atributo],tipo-objeto,[caminho-utilitrio]

Onde:
tag-name
Nome que identifica a tag HTML, onde em um formulrio INPUT, SELECT ou TEXTAREA.
Para uma tag customizada, geralmente um nome no formulrio de um HTML comentado, tipo
!-- MinhaTag. Usando comentrios para definir tags customizados minimiza a chance de
conflitos em verses futuras do HTML. Alm disso, as tags customizadas, diferente dos
elementos do formulrio, podem aparecer em qualquer lugar do HTML.
tag-encerramento
Nome da tag para fechar tags no HTML onde necessrio, tipo /TEXTAREA
tipo-atributo
O atributo TYPE para as tags <INPUT> e qualquer tag customizada ou futuras tags HTML que
necessitam um atributo TYPE como o TEXT ou HIDDEN.
tipo-objeto
O tipo do campo no SpeedScript que est no HTML ou tipo do tag customizado mapeado. Os
campos SpeedScript suportados so EDITOR, FILL-IN, RADIO-SET, TOGGLE-BOX e
SELECTION-LIST. No padro, estes tipos correspondem aos elementos HTML no formulrio o

CONTROLANDO TRANSAES WEBSPEED

mais semelhante possvel em formato como em funcionalidade. O SpeedScript suporta cada


objeto com um nico conjunto de capacidades provido por atributos e mtodos do SpeedScript.
caminho-utilitrio
O caminho do utilitrio tagmap que contm o padro das procedures web.input e web.output
para este HTML ou o tipo da tag customizada. Para a definio dos campos padro, este
caminho relativo para o PROPATH configurado. Quando um campo for customizado, estar
sendo recolocado do Control Handler provido pelo utilitrio tagmap correspondente. Caso o
utilitrio tagmap no seja especificado, deve-se sobrescrever o web.input e web.output no
AppBuilder para realizar uma tarefa equivalente.
Quaquer linha no tagmap.dat que inicia com o sinal # um comentrio.
Na pgina WEB exemplificada a seguir ilustrado como os campos definidos correspondem
aos elementos do formulrio em um arquivo HTML:
<HTML>
<BODY>
<FORM ACTION="exemplo.w" METHOD="post">
<CENTER>
<P><B>Entre com parte do<BR>ultimo nome do cliente:</B><BR>
<INPUT TYPE=text NAME="cust-prompt" SIZE=16 >
<INPUT TYPE=submit NAME="CustSearch" VALUE="Search"> </P>
</CENTER>
<P>Por favor entrar alguma parte inicial do nome do cliente
mesmo sendo a primeira letra.</P>
<SELECT NAME="matching-cust-names" SIZE=10> </SELECT>
<INPUT TYPE=submit NAME="CustDetail" VALUE="Show Detail" >
<P>
Name: <INPUT TYPE=text NAME="Name" SIZE=25 > <BR>
Phone: <INPUT TYPE=text NAME="Phone" SIZE=25 > <BR>
Comments: <TEXTAREA NAME="Comments" ROWS=6 COLS=60 ></TEXTAREA> <BR>
<BR>
Country:<BR>
USA <INPUT TYPE=radio NAME=Country VALUE=1><BR>
Other <INPUT TYPE=radio NAME=Country VALUE=2> <BR><BR>
Has Orders: <INPUT TYPE=checkbox NAME="HasOrders">
</P>
<INPUT TYPE=submit NAME="CustUpdate" VALUE="Update" >
</FORM>
</BODY>
</HTML>

Quando o utilitrio TagExtract gera o arquivo de offset para esta pgina WEB, usando o
arquivo tagmap.dat padro, o seguinte offset gerado:
/* HTML offsets */
htm-file= /working-directory-path/ncust-wo.htm
version= AB_v19r1
field[1]= "cust-prompt,INPUT,text,fill-in,11,1,11,45"
field[2]= "matching-cust-names,SELECT,,selection-list,21,1,21,53"
field[3]= "Name,INPUT,text,fill-in,26,10,26,47"
field[4]= "Phone,INPUT,text,fill-in,27,8,27,46"
field[5]= "Comments,TEXTAREA,,editor,28,11,28,63"
field[6]= "Country,INPUT,radio,radio-set,31,5,31,43"
field[7]= "Country,INPUT,radio,radio-set,32,7,32,45"
field[8]= "HasOrders,INPUT,checkbox,toggle-box,33,13,33,50"

possvel interromper a gerao do offset a qualquer momento no arquivo HTML, inserindo a


tag <!--TagExtractSuspend-> no ponto desejado. possvel ainda resumir a gerao do offset
insedrindo a tag <!--TagExtractResume-> no ponto desejado do arquivo.

CONTROLANDO TRANSAES WEBSPEED

O arquivo de offset registra cada tag mapeado (campo) na ordem de ocorrncias no arquivo
HTML. Para cada tag (field[6]), registrado o nome do atributo (COUNTRY), TYPE (INPUT),
visualizao no HTML (RADIO), o tipo do campo correspondente no SpeedScript (RADIO-SET)
do tagmap.dat e 4 inteiros que registram a linha inicial, caracter inicial, linha final e caracter final
da especificao da tag no arquivo HTML (31,5,31,43).
Para muitas aplicaes, o tagmap funciona perfeitamente usando as tags padres. Entretanto,
possvel recolocar o web.input e web.output padro para qualquer tag usando o template
como mostrado a seguir:
web.input
/*-----------------------------------------------------------------------Purpose: Assigns form field data value to frame screen value.
Parameters: p-field-value
Notes:
------------------------------------------------------------------------*/
DEFINE INPUT PARAMETER p-field-value AS CHARACTER NO-UNDO.
DO WITH FRAME {&FRAME-NAME}:
END.
END PROCEDURE.

web.output
/*-----------------------------------------------------------------------Purpose: Output the value of the field to the WEB stream
in place of the HTML field definition.
Parameters: p-field-defn
Notes:
------------------------------------------------------------------------*/
DEFINE INPUT PARAMETER p-field-defn AS CHARACTER NO-UNDO.
DO WITH FRAME {&FRAME-NAME}:
END.
END PROCEDURE.

Cada template passa os mesmo parmetros para toda tag. Para o web.input, isto o valor de
entrada corrente associado com a tag, expressado como caracter. Este valor atualmente a
sada da funo get-field() para o campo NAME HTML.
Para o web.output o parmetro o tag HTML completo especificado para o campo do arquivo
fonte HTML. Para um valor de sada, deve-se acessar o atributo SCREEN-VALUE do
SpeedScript do campo associado com a tag. possvel referenciar o atributo usando o nome
completo do campo do objeto. O nome do campo sempre tem o mesmo nome como o atributo
NAME para o tag associado (recolocando os espaos com underlines e removendo qualquer
caracter SpeedScript ilegal). Deste modo, para o campo NAME do HTML, possvel acessar o
valor do Frame Buffer usando NAME:SCREEN-VALUE.
Se o campo SpeedScript um RADIO-SET, o web.output executa uma vez para cada item do
objeto. Um segundo parmetro (o nmero do item) tambm passado dentro do control
handler.
Colocando os cdigos dentro do bloco DO padro garante que o objeto propriamente
referenciado no frame do SpeedScript. importante notar que, se o campo mapeado para um
campo de tabela, o nome do objeto pode ser prefixado pelo banco de dados e nomes de
tabelas separados por ponto (por exemplo, sports.customer.name), dependendo da
configurao do AppBuilder.
Finalmente, quando estiver criando tags customizadas, possvel criar seu prprio utilitrio
tagmap, como webinput.p. Entretanto, muito comum contar com o web.input e web.output no

CONTROLANDO TRANSAES WEBSPEED

objeto WEB, ao invs de definir um utilitrio em separado para a tag. Isto funciona quando o
tag customizado mapeia para campos padres do SpeedScript objetos como FILL-IN.

9.8. GERENCIANDO O TIME-OUT DO STATE-AWARE


Um time-out de um objeto WEB ocorre quando o perodo especificado no atributo Web-Timeout
do objeto WEB expira. Quando isto ocorre, um Agente que estava LOCKED altera seu estado
para AVAILABLE e destri o objeto WEB no processo (deste que nenhum outro objeto stateaware esteja ativo).
Entretanto, se o time-out ocorre, mas o Agente continua LOCKED, o Web-State do objeto
alterado para Timed-Out e o objeto no destrudo. possvel ainda acessar o objeto WEB
enquanto este Timed-Out ainda existir, at o Agente alterar o status para AVAILABLE. Se este
comportamento no o desejado, pode-se adicionar o seguinte cdigo no process-webrequest:
RUN get-attribute ("Web-State":U).
IF RETURN-VALUE = "Timed-Out" THEN DO:
RUN HtmlError IN web-utilities-hdl ("O objeto est com timed out!").
RETURN.
END.

Em geral, quando o usurio submete uma requisio de uma pgina retornada por um objeto
alterado para timed-out, a requisio contm no HTML incluso o cookie WSEU. O Transaction
Server retorna a seguinte mensagem:
The Web object to which you were attached has timed out. Please start again.

Se receber essa mensagem, 3 aes podem ser tomadas:


1- Setar o atributo Web-Timeout-Handler de state-aware, que permite executar outro
objeto WEB (.w) ou procedure WebSpeed (.p) quando o objeto WEB state-aware tem o
time-out.
2- Resetar o perodo do time-out para o objeto WEB state-aware sobrescrevendo a
procedure padro adm-timing-out.
3- Confiar na mensagem padro de time-out do WebSpeed Transaction Server.

9.8.1. Usando o Atributo Web-Timeout-Handler


Para usar o gerenciador de time-out do objeto WEB, deve-se setar o atributo Web-TimeoutHandler para o nome da procedure ou objeto WEB desejado para executar quando o perodo
expirar. necessrio apenas setar este atributo uma nica vez, sendo o melhor local para setar
esse atributo no MAIN BLOCK ou a procedure initialize.
RUN set-attribute-list IN THIS-PROCEDURE ("Web-Timeout-Handler = exemplo.w").

A procedure especificada como Web-Timeout-Handler armazenda em ambos os handles do


objeto WEB state-aware e como parte do cookie do objeto WEB. Isto suportar a situao onde
o perodo do objeto WEB state-aware expirar e eliminado. At se o objeto for eliminado, o
Web-Timeout-Handler pode tambm ser recuperado do cookie.
O exemplo a seguir um cabealho HTTP gerado pelo WebSpeed para um objeto WEB
contendo o atributo Web-Timeout-Handler:

CONTROLANDO TRANSAES WEBSPEED

Set-Cookie: WSEU=demeter:5604:22744:0; path=/cgi-bin/timeoff.sh


Set-Cookie: task.w=97,login.w ; path=/cgi-bin/timeoff.sh
Set-Cookie: employee.ssn=000000000; path=/cgi-bin/timeoff.sh
Content-Type: text/html

O Web-Timeout-Handler (login.w) adicionado para o fim do cookie do objeto WEB, que


contm o valor do atributo UNIQUE-ID da procedure do SpeedScript para o objeto WEB stateaware.
Depois do time-out, o WebSpeed recupera o nome do gerenciador do time-out do cookie do
objeto WEB state-aware expirado durante a prxima requisio e executa a procedure por este
nome. Se esta procedure um HTML-Mapping, o WebSpeed executar a seo do processweb-request que gerencia a mtodo de requisio apropriado, normalmente um POST.

9.8.2. Resetando o Tempo do Time-Out do Objeto WEB


Normalmente, quanto o perodo do objeto WEB expira, a procedure timingOut executa e altera
o estado do objeto para Timed-Out. Para resetar o perodo depois que expira o tempo, devese sobrescrever a procedure timingOut, executar a funo setWebState para dar ao objeto
WEB um novo perodo.
Para garantir que o objeto WEB tenha o time-out em algum ponto, a procedure local timingOut
deve ter a chamada para o timingOut padro quando a aplicao no precisar mais resetar o
perodo:
PROCEDURE timingOut :
/*-----------------------------------------------------------------------Purpose: Override standard ADM method
Notes:
------------------------------------------------------------------------*/
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */
IF get-user-field("Application-State") = "No-More-Changes" THEN
RUN SUPER.
ELSE
setWebState (60).
/* Code placed here will execute AFTER standard behavior. */
END PROCEDURE.

Neste exemplo, a aplicao seta o campo do usurio Application-State para No-MoreChanges quando estiver pronto para proceder time-out. Caso contrrio, quando qualquer timeout neste objeto WEB ocorrer, o perodo renovado para mais 60 minutos.
preciso ateno na lgica para verificar o cdigo usado para executar a procedure timingOut
padro. Caso essa procedure no seja executada nunca, o Agente que est executando o
objeto WEB state-aware permanecer locado porque o perodo ser sempre resetado.
possvel forar o time-out executando o setWebState na procedure outputHeader com o valor
igual a zero para o time-out.

CONTROLANDO TRANSAES NO BANCO DE DADOS

10. Controlando Transaes no Banco


de Dados
Uma transao uma unidade de trabalho, uma parte do cdigo que executada manipulando
o banco de dados, ou seja, que faz alguma mudana no banco de dados seja ela, uma criao,
uma atualizao ou uma eliminao. Esse trabalho pode ser completado como uma unidade ou
desfeito como uma unidade. O Progress usa processos de transaes para manter a
integridade dos dados. Esse captulo mostra como manter a integridade dos dados, como
identificar o incio e trmino da transao.
Para o Progress no existe um bloco transacional gravado pela metade ou cancelado pela
metade. Ou toda transao gravada ou toda cancelada.
importante administrar as transaes, pois so responsveis pelo balanceamento da
integridade dos registros com a concorrncia dos mesmos. Isto , quanto maior a transao,
mais registros que sofrem alterao estaro sendo presos neste bloco, mas impossibilitando o
seu acesso para manuteno em outros programas. O balanceamento destas duas variveis
importante para a performance, integridade e disponibilidade dos registros usados.
Para qualquer aplicao WebSpeed que atualiza o banco de dados, importante conhecer o
ponto onde a transao ter incio e quantas pginas requisitadas sero necessrias para
finalizar a mesma. Isto ir garantir que em caso de erro, ou queda do sistema, essa transao
ainda no finalizada, seja cancelada, ou caso tudo ocorra dentro do previsto, todas as
alteraes neste bloco transacional sejam gravados.

10.1. ESCOPO DE UMA TRANSAO


importante saber identificar como uma transao iniciada e identificar quanto ser gravado
ou desfeito. Primeiramente importante lembrar que a transao depende de um bloco e este
tem que ser um bloco forte para reter a transao, caso contrrio, a transao ser propagada
para o bloco anterior, at encontrar um bloco forte, onde o mais externo o prprio programa.
Qualquer bloco que usa a palavra chave TRANSACTION no comando do bloco(DO,
FOR ou REPEAT).
Qualquer procedure, trigger, blocos com DO ON ERROR, FOR EACH ou REPEAT que
diretamente alteram dados no banco de dados ou realizam leituras de registros com
EXCLUSIVE-LOCK.
Qualquer comando que altere registros no banco de dados transformar o bloco forte
onde est inserido em uma transao.
O escopo de uma transao deve ser tratado com cuidado, por exemplo, se uma procedure
chamada e dentro dela iniciada uma transao, apenas no final da procedure, os registros
alterados sero realmente gravados:
FOR EACH customer NO-LOCK:
RUN piExemplo(customer.state).
END.
PROCEDURE piExemplo:
DEFINE INPUT PARAMETER pState AS CHARACTER NO-UNDO.
FIND state WHERE state.state = pState EXCLUSIVE-LOCK NO-ERROR.
IF NOT AVAILABLE state THEN DO:
CREATE state.

CONTROLANDO TRANSAES NO BANCO DE DADOS

ASSIGN state.state = pState.


UPDATE state.state-name
state.region.
END.
END PROCEDURE.

Neste exemplo, para cada interao do bloco FOR EACH, uma transao ser iniciada no
bloco da procedure piExemplo, pois alm de ter o comando EXCLUSIVE-LOCK, existem
comandos para manipular registros para alterar seus valores no banco de dados.
Porm se o comando FOR EACH usar o EXCLUSIVE-LOCK, a transao ser iniciada no FOR
EACH. A procedure estar dentro desta transao. Neste exemplo, apenas no final da
interao do FOR EACH que a transao ser encerrada e os dados gravados.
FOR EACH customer EXCLUSIVE-LOCK:
RUN piExemplo(customer.state).
END.
PROCEDURE piExemplo:
DEFINE INPUT PARAMETER pState AS CHARACTER NO-UNDO.
FIND state WHERE state.state = pState EXCLUSIVE-LOCK NO-ERROR.
IF NOT AVAILABLE state THEN DO:
CREATE state.
ASSIGN state.state = pState.
UPDATE state.state-name
state.region.
END.
END PROCEDURE.

A chamada da procedure piExemplo j est dentro de uma transao, sendo assim, no


depende do fim de seu bloco para gravar as informaes e sim do bloco transacional onde ela
est inserida. No incio da interao do bloco FOR EACH, o WebSpeed inicia uma transao
no banco de dados. Se qualquer erro ocorrer antes do comando END, o WebSpeed desfaz
qualquer alterao realizada durante a transao.
Outra situao seria a existncia de diversas transaes em paralelo dentro de um programa.
DEFINE VARIABLE cLine AS CHARACTER NO-UNDO.
DEFINE VARIABLE i
AS INTEGER
NO-UNDO.
REPEAT:
CREATE order.
ASSIGN i = 1.
REPEAT:
CREATE order-line.
RUN GetField IN web-utilities-hdl("line" + TRIM(STRING(i)), OUTPUT cLine).
IF cLine = "" THEN
LEAVE.
ELSE DO:
CREATE order-line.
ASSIGN order-line.order-num = order.order-num.
{&DISPLAY} order-line.order-num.
ASSIGN order-line.line-num = i
i
= i + 1.
END.
END.
END.
FOR EACH salesrep EXCLUSIVE-LOCK:
{&DISPLAY} salesrep.sales-rep salesrep.rep-name.
ASSIGN salesrep.credit-limit = salesrep.credit-limit * 1.10.
END.

Este exemplo possui 4 blocos:

CONTROLANDO TRANSAES NO BANCO DE DADOS

PROCEDURE Todo programa ou procedure externa um bloco implcito. Entretanto,


neste caso no uma transao pois no foi usado nenhum comando que crie uma.
REPEAT Externo O bloco de REPEAT mais externo um bloco transacional, pois
possui comandos que realizam alteraes no banco de dados (CREATE order-line.).
Cada interao desse bloco, uma nova transao iniciada e no comando END deste
bloco, a transao encerrada, gravando as informaes. Se algum erro ocorrer antes
do comando END, as alteraes desta interao sero desfeitas.
REPEAT Interno uma sub-transao do REPEAT Externo. Mas possui sua prpria
transao, pois manipula registros no banco de dados diretamente. Entretanto, no final
da sua interao, as informaes no sero gravadas, pois esta sub-transao
depende da transao mais externa.
FOR EACH Este bloco tambm uma transao, pois altera registros no banco de
dados, alm destes registros serem lidos com a opo EXCLUSIVE-LOCK. Entretanto
no depende do bloco transacional criado pelo REPEAT Externo, pois est no mesmo
nvel e no dentro dele. A transao iniciada para cada interao do bloco.

10.2. SUB-TRANSAES
Uma sub-transao iniciada quando uma transao para um bloco j est ativa. importante
ressaltar que uma sub-transao um bloco dentro do outro bloco que tem uma transao. Se
um erro ocorre na sub-transao, toda alterao feita neste bloco desfeita, mas no
necessariamente a transao principal tenha o mesmo tratamento. Entretanto, para as
informaes alteradas da sub-transao serem gravadas, dependem da finalizao correta da
transao principal.
Podem existir diversos nveis transacionais dentro de um programa:
Bloco de uma procedure que executada a partir de um bloco transacional.
Cada interao de um FOR EACH que altere registros dentro de uma transao.
Cada interao de um REPEAT que altere registros dentro de uma transao.
Cada interao de um DO TRANSACTION, DO ON ERROR ou DO ON ENDKEY que
altere registros dentro de uma transao.

10.3. CONTROLANDO O INCIO E FIM DE UMA


TRANSAO
O controle de incio e fim de uma transao, deve ser feito pelo desenvolvedor. Para isso
importante conhecer os blocos, pois so neles que as transaes esto presas:
Blocos FOR EACH que atualizam o banco de dados.
Blocos REPEAT que atualizam o banco de dados.
Blocos PROCEDURE que atualizam o banco de dados.
Blocos DO ON ERROR ou DO ON ENDKEY que possuam comandos que alterem o
banco de dados.
A transao finaliza no comando END dos blocos ou quando a transao cancelada por
qualquer razo.
Dependendo da situao, pode ser necessrio que a transao seja maior ou menor de acordo
com a necessidade, lembrando que quanto menor a transao, menos ser desfeito em caso
de erro e quando maior a transao, maior ser o cancelamento das alteraes. Para isso pode
ser necessrio forar um bloco a ser uma transao, mesmo que naturalmente no seja. Para

CONTROLANDO TRANSAES NO BANCO DE DADOS

criar esse bloco transacional, necessrio usar o comando TRANSACTION nos blocos DO,
FOR EACH e REPEAT:
DO TRANSACTION:
FOR EACH TRANSACTION:
REPEAT TRANSACTION:
Caso j exista uma transao ativa, uma nova transao no ser aberta.

10.4. COMPONENTES DO SPEEDSCRIPT E TRANSAES


Alguns componentes do SpeedScript podem sofrer diferentes efeitos em blocos transacionais:
Sub-procedures
I/O de arquivos
Variveis dos programas

10.4.1. Sub-Procedures
Se uma transao for iniciada no programa principal, esta transao permanece ativa mesmo
quando esta procedure principal executar outras procedures, at mesmo outras procedures
externas.
FOR EACH customer EXCLUSIVE-LOCK:
RUN piExemplo(customer.state).
END.
PROCEDURE piExemplo:
DEFINE INPUT PARAMETER pState AS CHARACTER NO-UNDO.
FIND state WHERE state.state = pState EXCLUSIVE-LOCK NO-ERROR.
IF NOT AVAILABLE state THEN DO:
CREATE state.
ASSIGN state.state = pState.
UPDATE state.state-name
state.region.
END.
END PROCEDURE.

A transao foi iniciada no bloco FOR EACH e termina no comando END. Como a execuo da
procedure interna est dentro da transao, toda lgica existente na procedure est dentro da
transao. As alteraes realizadas na procedure executada sero gravadas apenas se a
interao do FOR EACH for encerrado corretamente. Caso contrrio, mesmo que a procedure
interna tenha realizada sua funcionalidade com exatido, caso o bloco FOR EACH seja
finalizado com erro, as informaes alteradas na procedure interna sero canceladas.

10.4.2. I/O de Arquivos


Deve-se tomar muito cuidado quando no processo transacional um arquivo lido de um
arquivo texto para popular um banco de dados.
Se um problema ocorrer, a transao ativa ser cancelada, mas no ser possvel saber
quanto foi processado e gravado do arquivo texto.
Para gerenciar isso, pode-se:

CONTROLANDO TRANSAES NO BANCO DE DADOS

Criar uma nica transao e fazer que todo o processo de gravao do arquivo texto
esteja nessa transao, ao invs de uma transao para cada linha lida do arquivo.
Entretanto, a transao pode ficar extremamente longa afetando a concorrncia e o
tamanho do arquivo Before Image (BI).
Por meio de programao, determinar se o registro a ser gravado j foi lido ou no,
mantendo assim uma transao por linha lida do arquivo, mas a lgica de programao
pode ser tornar mais complexa.

10.4.3. Variveis dos Programas


Toda varivel pode ter seu valor recuperado em caso de cancelamento de uma transao.
Tambm existe um processo de UNDO para as variveis. Entretanto, isto pode gerar muito
acesso a disco, pois o Progress armazena esses valores em arquivos temporrios, no caso, o
arquivo iniciado com LBI e precedido por uma numerao. Sendo assim, o valor inicial de
uma varivel pode ser recuperado no caso da transao no ser finalizada corretamente.
Caso uma varivel seja usada sem a necessidade de voltar a valores originais, aconselhvel
usar a opo NO-UNDO na definio da mesma.

10.5. TRANSAES NAS APLICAES


Nas aplicaes, as transaes podem ser afetadas pela distribuio dos componentes. Para
aplicaes que incluem bancos de dados mltiplos, o WebSpeed expande qualquer transao
para incluir todos os bancos de dados envolvidos. Para aplicaes que incluem o Progress
AppServer (aplicaes distribudas), cada componente da aplicao (Transaction Agent e
AppServer) controla separadamente as transaes.

10.5.1. Aplicaes com Mltiplos Bancos de Dados


Em uma aplicao com mltiplos bancos de dados, no necessrio codificar qualquer
gerenciamento de transao adicional. O processo tratado da mesma forma que em um nico
banco de dados. O mecanismo de Two-Phase Commit do WebSpeed garante que qualquer
transao seja gravada para todos os bancos de dados ou para nenhum em caso de erro.
necessrio apenas ter todos os bancos de dados a serem usados antes de iniciar a transao.
Two-Phase Commit
Durante uma transao, o WebSpeed grava dados em um ou mais bancos de dados de acordo
com os comandos de atualizao usados no bloco transacional. No final do bloco transacional,
o WebSpeed tentar gravar as alteraes nos bancos de dados. O WebSpeed usa o protocolo
Two-phase Commit para gravar as alteraes nos bancos de dados, onde o WebSpeed
analisa todos os bancos de dados afetados para verificar se esto disponveis.
Na primeira fase do Two-phase Commit, o WebSpeed verifica se pode acessar cada banco de
dados e realizar uma validao para cada banco de dados. Se qualquer um dos bancos de
dados no estiver disponvel ou existir qualquer falha de verificao para um banco de dados, o
WebSpeed cancela a transao e retorna a situao dos bancos de dados para o estado antes
da pr-transao usando o Before Image. Se todos os bancos de dados estiverem acessveis e
suas validaes corretas, o WebSpeed grava a alterao nos bancos de dados.

CONTROLANDO TRANSAES NO BANCO DE DADOS

Checando Conexes com Banco de Dados


A funo CONNECTED usada para verificar o estado dos bancos de dados:
IF CONNECTED("db1")
CONNECTED("db2")
RUN exemplo.p. /*
ELSE
RUN HTML-Error IN

AND
THEN
transaction block */
web-utilities-hdl("Incapaz de realizar a transao").

Deve-se conectar todos os bancos de dados afetados pela transao prioritariamente antes de
iniciar uma transao. Como uma regra geral, no se deve conectar um banco de dados dentro
de uma transao. A conexo do banco de dados pode travar registros em outros bancos de
dados afetados pela transao por um tempo consideravelmente longo. Alm do que uma
conexo de banco de dados pode falhar tambm causando um erro na transao. O
WebSpeed retarda o comando DISCONNECT em uma transao at que a transao esteja
completada ou desfeita.

10.5.2. Aplicaes Distribudas


Quando uma aplicao requisitada com uma transao ativa executa uma procedure remota, o
Progress no propaga a transao para a procedure remota. Certamente, a procedure remota
age como se fosse a primeira procedure da aplicao e segue as regras normais do
SpeedScript para iniciar e finalizar transaes. Se a aplicao requisitada e a procedure remota
conectam o mesmo banco de dados, cada conexo possui sua prpria transao.

10.6. DETERMINANDO QUANDO TRANSAES ESTO


ATIVAS
possvel usar a funo TRANSACTION para determinar se uma transao est ativa em um
bloco em tempo de execuo retornando YES.
Outra alternativa usar o comando COMPILE com a opo LISTING. No arquivo resultante
possvel identificar onde a transao ou transaes esto ativas.

10.7. TRANSAES EM MLTIPLAS PGINAS


O WebSpeed suporta transaes para mltiplas pginas state-aware requisitadas. Isto , se
uma transao iniciada na aplicao, existe a opo de iniciar uma transao no Transaction
Agent que continua na durao da transao do WebSpeed ou at a transao ser finalizada
explicitamente, seja desfazendo, repetindo ou confirmando a mesma. Alm disso, to longo
quanto ao menos um objeto WEB state-aware permanece ativo, possvel continuar iniciando
e finalizando transaes em mltiplas pginas.

10.7.1. Gerenciamento de Transaes com Mltiplas


Pginas
O mecanismo para controlar transaes em mltiplas pginas consiste de dois mtodos webutilities-hdl que podem executar no process-web-request:

CONTROLANDO TRANSAES NO BANCO DE DADOS

set-transaction-state(INPUT t-state), onde t-state pode ser:


- START[-PENDING] : Inicia uma transao com multiplas pginas quando esta
requisio terminar (Quando o Transaction Agent retorna para o estado LOCKED
ou no est mais no estado BUSY).
- UNDO[-PENDING] : Desfaz a transao de mltiplas pginas quando esta
requisio terminar.
- COMMIT[-PENDING] : Confirma a transao corrente de mltiplas pginas
quando esta requisio terminar.
- RETRY[-PENDING] : Desfaz a transao de mltiplas pginas corrente quando
esta requisio terminar e imediatamente inicia uma nova transao.
get-transaction-state retorna o estado da transao corrente como RETURN-VALUE de
uma funo, incluindo:
- NONE : No existe uma transao de mltiplas pginas ativa no Agente.
- START-PENDING : Uma transao de mltipla pgina deve ter sido iniciada no
Agente antes da requisio do prximo servio(Nenhuma transao no Agente
est atualmente ativo).
- ACTIVE : Existe uma transao de mltipla pgina ativa no Agente.
- "UNDO-PENDING" : Uma transao corrente de mltipla pgina ser desfeita no
incio da prxima requisio.
- "COMMIT-PENDING" : A transao corrente de mltiplas pginas ser atualizada
no incio da prxima requisio.
- "RETRY-PENDING" : A transao corrente de mltiplas pginas deve ser desfeita
e uma nova transao de mltiplas pginas ser iniciada no incio da prxima
requisio.
Como se pode ver, get-transaction-state pode retornar dois ou mais estados que podem setar o
set-transaction-state. Isto possvel porque quando uma transao de mltipla pgina
iniciada ou finalizada, no existe efeito at a prxima requisio na transao do Agente do
WebSpeed. Deste modo, o estado NONE significa que no existe uma transao ativa e
nenhuma foi requisitada. Do mesmo modo, o estado ACTIVE significa que existe uma
transao de mltiplas pginas ativa e nenhuma finalizao foi requisitada.
Entretanto, se existe o estado "UNDO-PENDING" ou "COMMIT-PENDING", existe uma
transao ativa que ser terminada na prxima requisio deste Agente. Enquanto o "RETRYPENDING" significa que uma transao ativa ser descardado e uma nova transao ser
ativada no incio da nova requisio.
importante notar que no possvel setar qualquer estado a qualquer momento. Alguns
estados obstruem outros e um erro retornado quando isto ocorre:
START pode apenas ser setado se o estado atual for NONE.
UNDO, RETRY e COMMIT podem somente ser setados se o estado atual for
ACTIVE.
Deste modo, no possvel alterar o estado previamente setado na mesma requisio.
Embora no seja possvel iniciar uma transao de mltiplas pginas quando nenhuma
transao estiver ativa no Agente, recebendo um erro ao tentar. O Agente (web-disp.p) resolve
a requisio da transao com o estado NONE como padro.

10.7.2. Trabalhando com Transaes de Mltiplas


Pginas

CONTROLANDO TRANSAES NO BANCO DE DADOS

O WebSpeed possui uma gerao de um objeto WEB HTML que permite iniciar e finalizar
transaes de mltiplas pginas.
Existe um exemplo no diretrio WebSpeed do Progress chamado tran-tst.w. Este programa
permite os campos CUST-NUM e NAME da tabela CUSTOMER. Existem botes para alterar o
objeto entre State-Aware e Stateless. Alm de botes para setar o estado da transao para
START, UNDO, RETRY e COMMIT.

Para testar o programa, deve-se seguir os passos:


1 Compilar e executar o tran-tst.w no broker.
2 Pressionar o boto State-Aware.
3 Pressionar o boto START. Esta requisio seta o web-disp.p para iniciar uma transao,
mas para a prxima requisio. Qualquer atualizao feita nessa requisio estar fora da
transao.
4 Pressionar o boto REFRESH para mostrar o estado da transao alterada para ACTIVE.
5 Digitar 1 no campo CustNum e New Name for Skiing no campo Name.
6 Pressionar o boto UPDATE.
7 Pressionar 2 no campo CustNum e New Name for Frisbee no campo Name.
8 Pressionar o boto UPDATE.
9 Continuar os passos 7 e 8 tanto quanto desejar.
10 Pressionar o boto UNDO. Isto far com que o web-disp.p desfaa as alteraes.
Entretanto, as alteraes no sero desfeitas at que a requisio termine. A lista de clientes
criada at a requisio corrente ainda mostrar os nomes alterados.
11 Pressionar o boto REFRESH. Neste momento os nomes alterados sero desfeitos.
Outro teste que pode ser feito :
1 Pressionar o boto START quando o objeto for Stateless.

CONTROLANDO TRANSAES NO BANCO DE DADOS

2 Pressionar Start duas vezes (o segundo acesso ocorre quando o estado da transao est
ACTIVE).
3 Pressionar UNDO, RETRY ou COMMIT quando no tiver nenhuma transao ativa.

10.7.3. Guia para Uso da Transao com Mltiplas


Pginas
A seguir algumas dicas para o entendimento do uso das transaes em mltiplas pginas:
Pelo menos um objeto WEB State-aware deve existir.
Executar o set-transaction-state(START) e:
- Observar que qualquer alterao feita no mesmo objeto enquanto o estado estiver
START no est na transao.
- O objeto WEB que muda o estado deve ser apenas de DISPLAY e no fazer
nenhuma alterao no banco de dados.
Continuar o processo de requisio neste Agente, mas lembrando que toda requisio
gerenciada pelo Agente ser feita nessa transao.
Se o usurio tiver um Agente locado e este Agente tem uma transao de mltiplas
pginas, ento tudo feito por este usurio estar na transao. necessrio ateno
neste caso. O usurio poder voltar para outra pgina ou tentar executar outro objeto.
Mesmo se estes no estiverem como State-aware, se o Agente execut-los, ento
suas alteraes estaro em uma transao.
Quando o usurio terminar, setar o estado para UNDO ou COMMIT, alm de setar o
objeto WEB para Stateless. importante lembrar que setando todos os objetos para
Stateless, automaticamente feito um UNDO a menos que a transao seja gravada
explicitamente dentro do tempo.
Se for decidido por setar para UNDO ou RETRY, lembrar que estas alteraes feitas
com a mesma requisio WEB tambm sero desfeitas. Isto :
RUN set-transaction-state IN web-utilities-hdl ("UNDO").
FIND LAST Customer EXCLUSIVE-LOCK NO-ERROR.
ASSIGN Customer.NAME = "SQLWorks Consultoria Ltda.".
{&OUT} "O nome " Customer.Name.

Este cdigo mostra um novo nome para Customer. Entretanto, a alterao ser
desfeita com o fim da transao.
Lembrar de considerar o caso do time-out do Agente. Isto tambm forar um UNDO
da transao em mltiplas pginas.
A imagem a seguir ilustra um modelo simplificado do fluxo da transao de mltiplas pginas
do WebSpeed:

CONTROLANDO TRANSAES NO BANCO DE DADOS

EXECUTANDO APLICAES

11. Executando Aplicaes


importante saber como preparar, setar, executar e debugar uma aplicao WebSpeed. Como
a aplicao executada no servidor e o resultado mostrado em um browser, a maneira de
interpretar o programa e identificar os possveis problemas diferente em relao ao ambiente
HOST-BASE e CLIENT/SERVER.

11.1. SETANDO O AMBIENTE DA APLICAO


importante saber como preparar o WebSpeed onde o Broker e os Agentes sero executados.
Diversas configuraes podem ser usadas, como o servidor WEB, Broker e Agentes no mesmo
servidor, ou dependendo do tamanho da aplicao e estrutura computacional da mquina,
pode-se usar mais de um servidor. Lembrando ainda que os bancos de dados utilizados
precisam estar em algum dos servidores usados.

11.1.1. Criando o Diretrio de Trabalho da Aplicao


necessrio criar um diretrio de trabalho para a aplicao WebSpeed. Normalmente, este
diretrio onde todos os arquivos da aplicao WEB usado, seja extenses .p, .w, .r, .off ou
.html, servindo tambm como diretrio de trabalho para o Broker e os Agentes, mas no
obrigatoriamente. Quando este diretrio especificado no Progress Explorer, ou no arquivo de
configurao ubroker.properties, dito ao Broker qual diretrio usar como diretrio de trabalho,
sendo tambm o diretrio de trabalho para todos os Agentes do Broker. Os sub-diretrios
criados no diretrio raiz de trabalho ou bibliotecas de procedures, assim como outros diretrios
podem ser adicionados ao PROPATH para o desenvolvimento da aplicao.
O diretrio de trabalho do Broker adicionado automaticamente ao PROPATH do Broker e dos
Agentes. Este diretrio normalmente referenciado por um ponto (.), sendo interpretado como
o diretrio corrente, mas no explicitamente. Caso os arquivos da aplicao sejam colocados
em um diretrio diferente, este diretrio deve ser adicionado ao PROPATH ou na execuo do
aplicativo, sempre referenciar em quais sub-diretrios os programas esto.

11.1.2. Movendo a Aplicao para o Diretrio Correto


Depois de criado o diretrio de trabalho, deve-se mover os arquivos da aplicao para este
diretrio. Entretanto, deve-se mover alguns arquivos para um diretrio apropriado do servidor
WEB.
Objetos WEB e Procedures
Quando uma procedure executvel for criada pelo AppBuilder, um objeto WEB foi criado. Em
alguns casos, como o HTML-Mapping, o arquivo HTML j deve existir, deste modo, este HTML
j deve ter sido criado por alguma outra ferramenta. Tambm pode ser necessrio, durante o
desenvolvimento, mover programas do WebSpeed (.w, .p, .i) para dentro do PROPATH,
possibilitando que os Agentes possam execut-las.
HTML e Outros Arquivos Estticos

EXECUTANDO APLICAES

Como descrito anteriormente, alguns arquivos HTML e imagens usadas podem nunca ser
processadas pelo WebSpeed. Estes arquivos so estticos se mantendo fixos do incio ao fim
da aplicao. possvel colocar estes arquivos no servidor WEB para que este possa ser
servido diretamente para o usurio. Entretanto, se o HTML gerado dinamicamente, estes
HTMLs devem ficar visveis para o Broker e os Agentes. O mais simples seria colocar estes
arquivos no diretrio de trabalho ou em algum diretrio do PROPATH.
Arquivos de Classes do Java
Os arquivos de classe do Java podem ser colocados em sub-diretrios do diretrio raiz do
servidor WEB, podendo ser referenciados no atributo CODEBASE da tag APPLET e o arquivo
de classe Java no atributo CODE da tag APPLET. Por exemplo, no arquivo de classe do Java,
sqlworks.class est no sub-diretrio java_classes do diretrio raiz do servidor WEB. Neste
caso, a tag ficaria:
<APPLET CODE=sqlworks.class CODEBASE=/java_classes></APPLET>
Arquivos JavaScripts
Estes arquivos JavaScripts (.js) devem ser colocados em um sub-diretrio do diretrio raiz do
servidor WEB, devendo referenciar o caminho relativo no atributo SRC da tag SCRIPT. Por
exemplo, no arquivo JavaScript sqlworks.js est no sub-diretrio javascript do diretrio raiz do
servidor WEB, ficando:
<SCRIPT LANGUAGE=JavaScript SRC=/javascript/sqlworks.js></SCRIPT>
TAGMAP.DAT
Se o arquivo padro alterado, a cpia modificada do tagmap.dat deve ser colocada no
diretrio de trabalho. Mas apenas se houver alterao do arquivo.
Arquivos de OFFSET
O arquivo de OFFSET (.off) criado quando o AppBuilder mapeia o arquivo HTML para um
objeto WEB. Os agentes usam as informaes deste arquivo para gerar dinamicamente uma
pgina HTML. Seu propsito dar a localizao dos campos de form do HTML para o arquivo
HTML. Para garantir que os Agentes localizem o arquivo de OFFSET, eles devem ser
colocados no diretrio onde o objeto WEB (r-code) est sendo executado. Se o arquivo de
OFFSET no o arquivo corrente de mapeamento para o objeto WEB HTML-Mapping, o
Agente cria um novo OFFSETa partir do arquivo HTML mapeado e do tagmap.dat disponvel.

11.1.3. Compilando Objetos WEB


Normalmente um programa compilado pelo AppBuilder durante o desenvolvimento, quando o
programa salvo, sendo necessrio apenas confirmar a pergunta que ser feita no momento
de salvar.
Em alguns casos, pode ser necessrio compilar diversos arquivos. Isto pode ser feito pela
interface WebTools, bastando selecionar a opo FILE da frame da esquerda do Browser, onde
ser mostrada uma lista de diversos arquivos que podem ser selecionados e compilados.
Outro aplicativo Progress que pode ser usado o Application Compiler. Entretanto, este
aplicativo no compila arquivos HTML, impossibilitando a compilao de fontes SpeedScript.

EXECUTANDO APLICAES

11.1.4. Tornando sua Aplicao Segura


Qualquer usurio da WEB pode executar qualquer procedure que esteja acessvel no
PROPATH do Agente, incluindo qualquer procedure que esteja no diretrio de trabalho ou nos
caminhos relativos dos diretrios de instalao do Progress. Por exemplo, se uma procedure
puder compilar e executar um programa digitado pelo usurio, essencialmente est sendo dado
controle sobre o Agente para este usurio. Alm disso, vrios comandos no SpeedScript
podem dar acesso a usurios ao sistema operacional.
Existem diversos tratamentos para evitar esta possibilidade. Uma delas seria iniciar o Agente
com o parmetro de Run Run-time Client (-rr), onde o Agente pode executar apenas programas
compilados. Com isto, possvel deixar os programas sem compilao no PROPATH, pois no
podero ser executados no browser. Entretanto, com isto perdido a vantagem da flexibilidade
de aproveitar o tempo de compilao no WebSpeed, que dependendo da aplicao, pode ser
necessrio. O uso da API check-agent-mode permite algumas rotinas a trabalharem em tempo
de desenvolvimento, mas no em tempo de produo.
Outra maneira seria retirar as procedures do PROPATH e colocar o caminho completo de
execuo das procedures, tirando a possibilidade de acesso direto de usurios pelo browser.
Com isto, estas procedures ficam impossibilitadas de serem executadas com o caminho
parcial.

11.2. INICIANDO E PARANDO UMA APLICAO


Para uma aplicao no WebSpeed, primeiramente os bancos de dados ou DataServers devem
estar carregados para depois carregar o Transaction Broker e os Agentes da aplicao. No
momento de parar a execuo da aplicao, o processo deve ser o contrrio, isto , primeiro
deve ser dado um shutdown no Broker e nos Agentes, para depois dar o shutdown nos bancos
de dados. Caso contrrio, os Agentes perdero as conexes com os bancos de dados
prematuramente e o sistema operacional ir intervir para completar o shutdown.

11.3. DEBUGANDO APLICATIVOS NO WEBSPEED


Para debugar um aplicativo no WebSpeed, preciso verificar as informaes no momento das
requisies da pgina WEB. A informao para debugar deve ser adicionada para cada pgina
WEB da aplicao gerada. Para este processo estar disponvel, preciso habilitar como
verdadeiro a varivel global debugging-enabled do WebSpeed.

11.3.1. Adicionando debug=on para URL


O WebSpeed Transaction Server permite visualizar informaes sobre as requisies W EB.
Para isto, deve adicionar o argumento (debug=on) para a URL normalmente utilizada para
acessar a aplicao WebSpeed:
http://webserver/cgi-bin/webapp.cgi/login.w
Este seria o normal para a execuo do programa login.w.
http://webserver/cgi-bin/webapp.cgi/login.w?debug=on

EXECUTANDO APLICAES

O programa login.w executado normalmente, entretanto, quando o WebSpeed finaliza a


execuo do programa, a procedure para debugar executada. A sada da procedure aparece
no browser diretamente abaixo da sada da aplicao. Pelo padro, o WebSpeed executa a
debugao da procedure depois de sua aplicao para minimizar qualquer problema com a
sada das informaes do debugador para evitar afetar a aplicao.

11.3.2. Debugando com Cookies


O processo de debugar funciona melhor usando browser que suportam Cookies de estados
persistentes. Sem os Cookies, toda URL dever ter a sintaxe para setar o atributo debug
(debug=on) na aplicao para garantir que esta caracterstica seja mantida nas demais pginas
requisitadas. Usando o Cookie, o debugador corrente seta e usa este valor at ser
explicitamente excludo.
Existem vrias sesses na sada para a pgina requisitada no WebSpeed. Cada uma dessas
sesses tem uma opo associada independente das outras.

11.3.3. Chamando o Debugador Virtual do Objeto WEB


Cada instalao do WebSpeed tem acesso ao debugador virtual do objeto WEB, que pode ser
invocado para iniciar uma sesso debugando uma aplicao. Para invocar o debugador, devese adicionar ao Messenger na URL do WebSpeed:
http://webserver/cgi-bin/webapp.cgi/debug
Invocando essa URL do browser, o WebSpeed ativa o Administration Form para iniciar o debug
na execuo da aplicao. Este Form possui diversas opes para controlar a sesso
debugada.

11.3.4. Debugando e Opes Administrativas


Esta sesso aparece na parte de baixo da sada do debug, fornece uma interface com todas as
opes debugadas conhecidas, permitindo habilita-las ou no. possvel tambm adicionar
suas prprias opes especficas da aplicao para debugar, adicionando-as no campo da
opo debug corrente ou na URL.
O valor mostrado depois do Debugging Cookie WSDebug o valor corrente do Cookie. Pelo
funcionamento do Cookie, o valor apresentado est sempre uma pgina atrasada em relao
apresentada em tela, sempre por uma requisio.
Para sincronizar o Cookie com a opo de debug, deve-se alterar a opo de degugao como
desejado e acessar o boto apropriado para set-lo. Isto seta o WSDebug Cookie
corretamente. Deve-se ento clicar no boto de Reload no form e no no browser, para
submeter pgina e recarreg-la. O valor do Current Debug e WSDebug Cookie so idnticos.
possvel descer at o fim da pgina e retornar ao topo e executar a aplicao normalmente.
Mesmo que as opes de debug setadas permaneam ativas at serem explicitamente
alteradas. Entretanto, essas opes para debugar so setadas especificamente na URL da
aplicao. O WSDebug Cookie setado com o caminho baseado no valor da varivel AppURL.
Isto faz com que o browser somente envie o Cookie quando visitando qualquer URL iniciada
com o mesmo caminho.

EXECUTANDO APLICAES

Se o browser utlizado no suportar Persistent State Cookies, o valor do WSDebug Cookie ser
branco.
Outras opes so:
ON = Habilita todos os debugs.
OFF = Desabilita todos os debugs.
ALL = ON.
Tambm possvel especificar mltiplas opes para debugar na URL. Qualquer das opes
listadas acima podem ser combinadas. Por exemplo, para testar caracterstica State-Aware,
deve-se:
http://webserver/cgi-bin/webapp.cgi/webapp.w?debug=agent,cookies,http
Isto retorna a sada do arquivo webapp.w seguido por sesses de debugger. Caso seja
desejado o form Debugging e Administration, a opo Admin deve ser especificada
explicitamente a menos que as opes genricas, on e all sejam usadas. Tambm
possvel especificar esta lista no campo de opes Current Debug das opes do Form
Debugging e Administrative.
Desligar o debug similar a ligar. Basta clicar no link da opo do Debugging e Administrative
ou especificar debug=off como argumento na URL. Basta ento recarregar o browser.
Informao Especfica do Agente
Esta sesso contm informaes especficas para o processo Agente que gerencia as
requisies.
Persistent State Cookies
Esta sesso contm uma lista de todos os nomes de cookies recebidos pelo browser e o valor
de cada um.
Cabealhos de HTTP Enviados
Esta sesso lista todos os cabealhos HTTP enviados para o browser (Por exemplo, SetCookie: e Content-Type:). Esta sesso deve mostrar somente se a opo HTTP especificada
na URL ou na Form Administration.
Variveis Diversas (Micelneas)
Esta sesso contm variveis usadas internamente pelo WebSpeed Transaction Server, que
pode tambm ser usado na aplicao WebSpeed. A varivel SelfURL sempre a URL da
pgina corrente (exceto os argumentos), e a varivel AppURL a URL da sua aplicao. Essas
variveis so derivadas das variveis de ambiente SCRIPT_NAME e PATH_INFO.
Variveis de Ambiente
Esta sesso contm todas as variveis de ambiente passadas para o processo do Messenger
do WEB Server. Muitas dessas variveis so herdadas pelo WEB Server onde foi iniciada.
Outras variveis so alteradas de requisio para requisio.
Form Fields
Esta sesso contm campos listados na forma pura que so retornadas pela funo get-field().
Esta sesso contm somente valores se a requisio o resultado do form de entrada ou se
qualquer argumento especificado seguindo o ? na URL.

EXECUTANDO APLICAES

11.3.5. Utilizando o Debugador na Aplicao


Qualquer aplicao WebSpeed tem acessa as variveis globais de opes de debug do
WebSpeed. Estas variveis podem ser setadas para debugar usando de opes separadas por
vrgula. Deste que o objeto WEB escrito em SpeedScript tenha a include
{src/web/method/cgidefs.i}, o que padro, estas variveis so acessveis.
As opes que podem ser setadas incluem cookie, http e all, alm de outras. A lista completa
das opes est em instalao-progress/src/web/support/prinval.p, que a procedure
WebSpeed que d a sada das informaes analisadas pelo debug para as pginas WEB.
Para testar se all (todos) as opes para debugar esto habilitadas, fazer:
IF CAN-DO(debug-options, all) THEN DO:
/* Cdigo */
END.
A funo CAN-DO() compara o segundo argumento com o primeiro, que deve ser uma lista
separada por vrgulas das opes. Se a a palavra all for encontrada na lista, retorna TRUE e
executa o SpeedScript do bloco.
O prximo cdigo teste para uma opo de debug customizada chamada login ao invs de
all:
IF CAN-DO(debug-options, login) OR CAN-DO(debug-options, all) THEN DO:
/* Cdigo */
END.
Se for especificado debug=login, debug=all a sesso ser executada.
Se usar opes prprias de debug, necessrio ter certeza que a aplicao ignorar todas as
opes que no forem entendidas. No se deve testar o valor da varivel de debug-options por
igualdade. Sempre testar usando a funo CAN-DO() para verificar se as opes customizadas
so entre as listadas.

11.3.6. Arquivos de LOGs do Broker e Agentes


Todas as mensagens originados pelo Broker ou agentes, so escritas em arquivos de logs de
erros. Esses arquivos podem ser analisados para extrair as informaes sobre a aplicao.
Algumas informaes ainda podem ser escritas no arquivo .lg dos bancos de dados.

Você também pode gostar