• Nenhum resultado encontrado

Convertendo SmartObjects para DBO 2.0

No documento Construção de DBOs 2.0 (páginas 59-69)

Convertendo SmartObjects para DBO 2.0

Este capítulo é destinado ao desenvolvedor que utiliza SmartObjects e deseja convertê-los para DBOs 2.0.

Para converter um SmartObject devem ser seguidos os seguintes passos:  Criar um novo DBO 2.0;

 Transferir lógicas dos métodos dos SmartObjects para o DBO 2.0. A seguir são detalhados os passos:

Criar o novo DBO

Este passo está detalhado no item 'Construindo o DBO'.

Transferir lógicas dos métodos dos SmartObjects para o DBO

2.0

Quando se trabalha com SmartObjects, a lógica de navegação, leitura, consulta, alteração, etc. está em diferentes programas. Por exemplo: a lógica de navegação está na SmartQuery, a lógica de gravação está em várias SmartViewers, etc.

Mas ao utilizar DBOs toda a lógica de tratamento de registro encontra-se no DBO. Através disto, basta o desenvolvedor transferir as lógicas dos

SmartObjects para os DBOs, conforme descrito a seguir:  SmartQuery

Toda a lógica de abertura de query deve ser transferida para os métodos openQuery<Description>. Além disso, caso a SmartQuery faça uso de mais de

uma tabela, isto deve ser substituído pelo uso do método setConstraint<Description> e linkTo<Description>.

E, ainda, todas as restrições impostas à abertura da query, também devem ser transferidas para seus respectivos métodos setConstraint<Description>. A seguir, um exemplo, no qual a SmartQuery possuía a tabela Customer e a tabela SalesRep, como tabela estrangeira.

DEFINE VARIABLE cSales-Rep LIKE Customer.Sales-Rep NO-UNDO. PROCEDURE openQueryMain:

IF cSales-Rep = "" THEN OPEN QUERY {&QueryName}

FOR EACH Customer NO-LOCK. ELSE

OPEN QUERY {&QueryName} FOR EACH Customer

WHERE Customer.Sales-Rep = cSales-Rep NO-LOCK.

END PROCEDURE.

PROCEDURE openQueryByName: IF cSales-Rep = "" THEN OPEN QUERY {&QueryName}

FOR EACH Customer NO-LOCK BY Customer.Name. ELSE

OPEN QUERY {&QueryName} FOR EACH Customer

WHERE Customer.Sales-Rep = cSales-Rep NO-LOCK BY Customer.Name.

END PROCEDURE.

PROCEDURE openQuerySalesRep: OPEN QUERY {&QueryName} FOR EACH Customer

WHERE Customer.Sales-Rep = cSales-Rep NO-LOCK.

END PROCEDURE.

PROCEDURE setConstraintSalesRep:

DEFINE INPUT PARAMETER pSales-Rep LIKE Customer.Sales-Rep NO- UNDO.

ASSIGN cSales-Rep = pSales-Rep.

RETURN "OK":U. END PROCEDURE.

PROCEDURE linkToSalesRep:

DEFINE INPUT PARAMETER pHandle AS HANDLE NO-UNDO.

CAPÍTULO 5 Convertendo SmartObjects para DBO 2.0 59

RUN getKey IN pHandle (OUTPUT cSalesAux).

RUN setConstraintSalesRep IN THIS-PROCEDURE (INPUT cSalesAux). END PROCEDURE.

Neste exemplo, foram definidos 3 (três) métodos de abertura de query, pois o DBO normalmente é único por tabela. Sendo assim, criou-se os métodos setConstraintSalesRep e linkToSalesRep.

Estes métodos serão utilizados para fazer a comunicação entre um DBO Pai (SalesRep) e um DBO Filho (Customer), porém o DBO Filho também terá opções de aberturas independente do DBO Pai.

 SmartViewer

Toda a lógica de gravação da viewer deve ser transferida para os métodos before/afterCreateRecord ou before/afterUpdateRecord.

A seguir, um exemplo, no qual a SmartViewer fazia a gravação automática do campo cust-num no momento de criação do registro.

Método Antigo:

DEFINE BUFFER bfCustomer FOR Customer. PROCEDURE local-create-record:

DEFINE VARIABLE iCust-Num AS INTEGER NO-UNDO.

FIND LAST bfCustomer NO-LOCK NO-ERROR. IF AVAILABLE bfCustomer THEN

ASSIGN iCust-Num = bfCustomer.Cust-Num + 1. ELSE

ASSIGN iCust-Num = 1.

RUN dispatch IN THIS-PROCEDURE ("create-record":U). IF RETURN-VALUE = "ADM-ERROR":U THEN

RETURN "ADM-ERROR":U.

ASSIGN Customer.Cust-Num = iCust-Num. END PROCEDURE.

Método Novo:

DEFINE BUFFER bfCustomer FOR Customer. PROCEDURE beforeCreateRecord:

DEFINE VARIABLE iCust-Num AS INTEGER NO-UNDO.

FIND LAST bfCustomer NO-LOCK NO-ERROR. IF AVAILABLE bfCustomer THEN

ASSIGN iCust-Num = bfCustomer.Cust-Num + 1. ELSE

ASSIGN RowObject.Cust-Num = iCust-Num. RETURN "OK":U.

END PROCEDURE.

Neste exemplo, foi definido o método beforeCreateRecord para realizar a atualização do campo cust-num. Vale salientar que somente será atualizado este campo se for feita uma criação.

A seguir, um exemplo, no qual são feitas atualizações comuns a criação e alteração de registro da tabela Customer:

Método Antigo:

PROCEDURE local-assign-record:

RUN dispatch IN THIS-PROCEDURE ("assign-record":U). IF RETURN-VALUE = "ADM-ERROR":U THEN

RETURN "ADM-ERROR":U.

ASSIGN Customer.Credit-Limit = Customer.Credit-Limit * 1.10. END PROCEDURE.

Método Novo:

PROCEDURE before_copyTT2Buffer:

ASSIGN RowObject.Credit-Limit = RowObject.Credit-Limit * 1.10.

RETURN "OK":U. END PROCEDURE.

Neste exemplo, criou-se o método before_copyTT2Buffer. O qual é executado antes da transferência dos dados da temp-table RowObject para a tabela principal do DBO.

A seguir, um exemplo, no qual são feitas validações de criação de registro: Método Antigo:

PROCEDURE local-assign-record:

DEFINE VARIABLE iCust-Num AS INTEGER NO-UNDO.

ASSIGN iCust-Num = INTEGER(Customer.Cust-Num:SCREEN-VALUE IN FRAME {&FRAME-NAME}).

IF adm-new-record THEN

IF CAN-FIND(Customer WHERE Customer.Cust-Num = iCustNum) THEN DO:

RUN utp/ut-msgs.p (INPUT "SHOW":U, INPUT <ErrorNumber> INPUT <ErrorParameters>). RETURN "ADM-ERROR":U.

CAPÍTULO 5 Convertendo SmartObjects para DBO 2.0 61

RUN dispatch IN THIS-PROCEDURE ("assign-record":U). IF RETURN-VALUE = "ADM-ERROR":U THEN

RETURN "ADM-ERROR":U. END PROCEDURE.

OBSERVAÇÃO: O utilitário UTP/UT-MSGS.P era utilizado em SmartObjects, porém, não deverá ser utilizado em DBOs, conforme conceito da tecnologia de DBOs.

Método Novo:

PROCEDURE beforeCreateRecord:

IF CAN-FIND(Customer WHERE Customer.Cust-Num =

RowObject.Cust-Num) THEN DO: {method/svc/errors/inserr.i &ErrorNumber="9999" &ErrorType="EMS" &ErroSubType="ERRO" &ErrorParameters="''"} RETURN "NOK":U. END. RETURN "OK":U. END PROCEDURE.

Neste exemplo, foi definido o método beforeCreateRecord para realizar a validação de registro duplicado. Vale salientar que somente será executada esta validação quando for feita a criação de registros.

A seguir, um exemplo, no qual são feitas validações comuns à criação e alteração de registro:

Método Antigo:

PROCEDURE pi-validate: {include/i-vldfrm.i}

IF Customer.Name = "":U THEN DO: {include/i-vldprg.i}

RUN utp/ut-msgs.p (INPUT "SHOW":U, INPUT <ErrorNumber>, INPUT <ErrorParameters>).

APPLY "ENTRY":U TO Customer.Name IN FRAME {&FRAME-NAME}.

RETURN "ADM-ERROR":U. END.

OBSERVAÇÃO: O utilitário UTP/UT-MSGS.P era utilizado em SmartObjects, porém, não deverá ser utilizado em DBOs, conforme conceito da tecnologia de DBOs.

Método Novo:

PROCEDURE validateRecord:

IF RowObject.Name = "":U THEN {method/svc/errors/inserr.i &ErrorNumber="9999" &ErrorType="EMS" &ErroSubType="ERROR" &ErrorParameters="''"}

IF CAN-FIND(FIRST RowErrors) THEN RETURN "NOK":U.

RETURN "OK":U. END PROCEDURE.

Neste exemplo, foi definido o método validateRecord para realizar a validação sobre o campo name. Vale salientar que este método será executado tanto na criação como na alteração de registros.

A seguir, um exemplo, no qual são feitas validações de eliminação de registro: Método Antigo:

PROCEDURE local-delete-record:

IF CAN-FIND(FIRST Order OF Customer) THEN DO: RUN utp/ut-msgs.p (INPUT "SHOW":U, INPUT <ErrorNumber>, INPUT <ErrorParameters>). RETURN "ADM-ERROR":U. END.

RUN dispatch IN THIS-PROCEDURE ("delete-record":U). END PROCEDURE.

OBSERVAÇÃO: O utilitário UTP/UT-MSGS.P era utilizado em SmartObjects, porém, não deverá ser utilizado em DBOs, conforme conceito da tecnologia de DBOs.

Método Novo:

PROCEDURE beforeDeleteRecord:

IF CAN-FIND(FIRST Order OF RowObject) THEN {method/svc/errors/inserr.i

CAPÍTULO 5 Convertendo SmartObjects para DBO 2.0 63

&ErrorType="EMS" &ErroSubType="ERRO" &ErrorParameters="''"}

IF CAN-FIND(FIRST RowErrors) THEN RETURN "NOK":U.

RETURN "OK":U. END PROCEDURE.

Neste exemplo, foi definido o método beforeDeleteRecord para realizar a validação a fim de verificar se o registro pode ser eliminado.

 Triggers de Dicionário

Quando utilizada uma trigger de create, toda a lógica deve ser transferida para o método beforeCreateRecord.

A seguir, um exemplo, no qual são setados valores automaticamente para a tabela Customer:

Método Antigo:

TRIGGER PROCEDURE FOR create OF customer.

ASSIGN Customer.Cust-Num = NEXT-VALUE(next-cust-num). Método Novo:

DEFINE BUFFER bfCustomer FOR Customer. PROCEDURE beforeCreateRecord:

FIND LAST bfCustomer NO-LOCK NO-ERROR. IF AVAILABLE bfCustomer THEN

ASSIGN RowObject.Cust-Num = bfCustomer.Cust-Num + 1. ELSE

ASSIGN RowObject.Cust-Num = 1.

RETURN "OK":U. END PROCEDURE.

Neste exemplo, foi criado o método beforeCreateRecord para realizar a gravação automática do campo cust-num, no momento de criação do registro. Quando utilizada uma trigger de delete, toda a lógica de validação deve ser transferida para o método beforeDeleteRecord e a lógica de eliminação em cascata deve ser transferida para o método afterDeleteRecord.

A seguir, um exemplo, no qual é feita a eliminação em cascata de registros: Método Antigo:

TRIGGER PROCEDURE FOR delete OF customer. FOR EACH Order OF Customer:

DELETE Order. END.

Método Novo:

PROCEDURE afterDeleteRecord: FOR EACH Order OF RowObject: DELETE Order.

END.

RETURN "OK":U. END PROCEDURE.

Neste exemplo, foi criado o método afterDeleteRecord para realizar a eliminação em cascata da tabela Order.

Quando utilizado uma trigger de write, toda a lógica de validação deve ser transferida para o método validateRecord (quando estas forem comuns à criação e alteração) ou beforeUpdateRecord (quando estas forem pertinentes à alteração) .

A lógica de atualização deve ser transferida para o método

before_copyTT2Buffer (quando estas forem comuns à criação e alteração) ou para o método beforeUpdateRecord (quando estas foram pertinentes à alteração) ou para o método afterUpdateRecord (quando estas foram atualizações em cascata).

A seguir, um exemplo, no qual são feitas validações comuns à criação e alteração; atualizações automáticas de campos da tabela customer; atualizações em cascata de outras tabelas:

Método Antigo:

TRIGGER PROCEDURE FOR write OF customer OLD BUFFER oldcustomer. IF Customer.Name = "":U THEN DO:

RUN utp/ut-msgs.p (INPUT "SHOW":U, INPUT <ErrorNumber>, INPUT <ErrorParameters>). RETURN ERROR.

END.

IF Customer.Address2 = "":U THEN

ASSIGN Customer.Address2 = Customer.Address.

IF Customer.Cust-Num <> oldCustomer.Cust-Num THEN FOR EACH Order OF oldCustomer:

ASSIGN Order.Cust-Num = Customer.Cust-Num. END.

CAPÍTULO 5 Convertendo SmartObjects para DBO 2.0 65

OBSERVAÇÃO: O utilitário UTP/UT-MSGS.P era utilizado em SmartObjects, porém, não deverá ser utilizado em DBOs, conforme conceito da tecnologia de DBOs.

Método Novo:

PROCEDURE validateRecord:

IF RowObject.Name = "":U THEN {method/svc/errors/inserr.i &ErrorNumber="9999" &ErrorType="EMS" &ErroSubType="ERRO" &ErrorParameters="''"}

IF CAN-FIND(FIRST RowErrors) THEN RETURN "NOK":U.

RETURN "OK":U. END PROCEDURE.

PROCEDURE before_copyTT2Buffer: IF RowObject.Address2 = "":U THEN

ASSIGN RowObject.Address2 = RowObject.Adress.

RETURN "OK":U. END PROCEDURE.

PROCEDURE beforeUpdateRecord:

IF RowObject.Cust-Num <> Customer.Cust-Num THEN FOR EACH Order OF Customer:

ASSIGN Order.Cust-Num = RowObject.Cust-Num. END.

END PROCEDURE.

Neste exemplo, foi criado o método validateRecord para realizar validações comuns à criação e alteração de registro. E ainda, o método

before_copyTT2Buffer para realizar atualizações comuns à criação e alteração. E, além disso, o método beforeUpdateRecord para realizar atualizações em cascata pertinentes à alteração.

Observação: Ao retirar as lógicas de negócio das triggers de dicionário, deve- se manter as chamadas de UPCs nas triggers.

 SmartBrowse

Os SmartBrowses devem ser analisados conforme sua funcionalidade.

Caso o SmartBrowse seja utilizado para navegação, deve-se seguir as mesmas regras sugeridas para SmartQuery. Mas, caso o SmartBrowse seja utilizado

para update (inclusão/alteração/exclusão) deve-se seguir as mesmas regras sugeridas para SmartViewer.

67

No documento Construção de DBOs 2.0 (páginas 59-69)

Documentos relacionados