Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring

_Créditos das imagens: ChatGPT_ ### LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring Resolver o problema do [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/description/) é um exercício clássico de programação, que desafia desenvolvedores a encontrar a maior substring palindrômica dentro de uma string. Recentemente, exploramos soluções tanto em Harbour quanto em TLPP (Total Language Protheus Programming). Neste artigo, comparamos as implementações nessas duas linguagens, destacando suas semelhanças, diferenças e funcionalidades específicas. #### Implementações em Harbour ##### Versão 5.1 Essa solução utiliza a técnica de expansão a partir do centro do palíndromo. Cada caractere ou par de caracteres consecutivos é considerado um possível "centro". O algoritmo expande em ambas as direções enquanto os caracteres forem iguais, retornando o maior palíndromo encontrado. ##### Versão 5....

Protheus :: Advpl :: Criando Pontos de Restauração

A idéia do “Ponto de Restauração” surgiu devido a uma necessidade específica. Foram customizadas algumas rotinas no Cliente que usavam tabelas padrões e customizadas do sistema mas que não tinham histórico. Ex.: SRA, CT1, CTT, etc. O desejo do cliente, era, além de poder emitir relatório com os Dados da época em que foram gerados era, em algum momento, poder refazê-los baseado na sua configuração original.

Conversando com Luis Felipe Nascimento (Totvs RJ) chegamos ao consenso que a melhor forma de fazer isso seria via “Ponto de Restauração” onde salvaríamos as informações das tabelas (campos específicos ou Registros inteiros) de forma a poder restaurá-las a qualquer momento.

Uma das premissas básicas era que a Restauração de um Ponto específico não deveria interferir e nem influenciar o ambiente de Produção, e por isso, definimos que ele só poderia ser efetuado em uma cópia desse ambiente. Considerando, também, que alguns arquivos de configuração do sistema eram passíveis de serem “salvos/restaurados” não poderíamos utilizar o mesmo RoothPath. Sendo assim teríamos uma cópia deste.

Como regra, o “Environment” para restauração deveria conter:

Nome do Ambiente Original + chave + RESTORE como no exemplo:

[ndj_01] refere-se ao ambiente de produção, já: [ndj_01_rp_restore] refere-se ao ambiente de restauração a configuração do ini, então, ficaria como:

[ndj_01]
SourcePath=D:\totvs\p10\ndj\rpo\ndj_01\
RootPath=D:\totvs\p10\ndj\pdata
StartPath=\system\
RpoDb=SQL
RpoLanguage=Portuguese
RpoVersion=101
LocalFiles=ads
localdbextension=.dbf
PictFormat=DEFAULT
DateFormat=DEFAULT
REGIONALLANGUAGE=BRA
topDataBase=MSSQL
topServer=127.0.0.1
TopAlias=naldo

e  o de restauração:

[ndj_01_rp_restore]
SourcePath=D:\totvs\p10\ndj\rpo\ndj_01\
RootPath=D:\totvs\p10\ndj\pdata_ndj_01_rp_restore
;RootPath=D:\totvs\p10\ndj\pdata
StartPath=\system\
RpoDb=SQL
RpoLanguage=Portuguese
RpoVersion=101
LocalFiles=ads
localdbextension=.dbf
PictFormat=DEFAULT
DateFormat=DEFAULT
REGIONALLANGUAGE=BRA
topDataBase=MSSQL
topServer=127.0.0.1
TopAlias=naldo_rp

Além disso, a rotina deveria permitir a customização do “Ponto de Restauração” permitindo a Definição de Vários Tipos de Ponto de Restauração. Para isso, definimos que a configuração deveria ser através de um arquivo .ini que conteria a regra para a criação e restauração de um Ponto conforme modelo:

[GENERAL]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define a chave com a customização dos diretórios a serem utilizados durente o processo
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CustomPath=NDJRPCustomPath
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define as Tabelas que terão os conteúdos salvos
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Tables=CT2,CTT,CT1,SRA,ZZ2,ZZ3,ZZ4,ZZ5,SX5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define a extensão do arquivo
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dbExtensiom=.dbf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define as Tabelas de Sistema que terão os conteúdos salvos
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TConfig=SX6,SX1,SX3,SIX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define se o arquivo de senhas também deverá ser salvo
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PWDFile=sigapss.spf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define a chave/tipo de Ponto de Restauração
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KeyEnvRestore=_RP_;

[NDJRPCustomPath]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define o Diretório Principal onde os arquivos do Ponto de Restauração Estarão armazenados
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RootPath=\ndj_rp\
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define o Diretório onde os arquivos da chave Tables serão gravados
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PathData=\data\
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define o Diretório onde os arquivos da chave TConfig serão gravados
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PathSXS=\system\
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define o Diretório onde o arquivo configurado na chave PWDFile será gravado
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PathPWD=\pwd\
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define a expressão para a criação de um Path Dinamico. Sempre deverá conter cEmpAnt + uma expressão Advpl válida.
;Poderá ser uma user function ou a chamada a uma Fórmula Formula("RP1") por exemplo
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PathCustomExpr=cEmpAnt+"_RP_"+SubStr(Dtos(MsDate()),1,4)+"_"+SubStr(Dtos(MsDate()),5,2)+"_"+SubStr(Dtos(MsDate()),7,2)+"_"+StrTran(Time(),":","_")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define o Diretório Virtual
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RestoreSystemVPath=\system_vlink\

[CTT]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define o(s) campos a serem Salvos. * para todos os campos ou os campos específicos
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Fields=*;CTT_MSBLQL,CTT_BLOQ,CTT_XALOCA,CTT_XTPALC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Chave, preferencialmente o X2_UNICO ou a mais abrangente (que garanta a unicidade dos registros)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IndexKey=CTT_FILIAL+CTT_CUSTO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Expressao de Friltro a ser utilizado. Dependendo da chave SQLFilter, se SQLFilter=1 expressão SQL, SQLFilter=0 expressão advpl
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Filter=CTT_XALOCA='T'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Ativa o Filtro @
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SQLFilter=1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define o RDD a ser utilizado na "exportação"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rddExport=DBFCDXADS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define o RDD a ser utilizado na "Restauração"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rddImport=TOPCONN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define se a tabela será restaurada: NoRetore=1 Não Restaura a Tabela, NoRetore=0 restaura
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;NoRetore=1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Define se irá utilizar ChkFile na abertura das tabelas. Por padrão 1, para as tabelas de sistema deverá ser 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ChkFile=1

…mais informações no arquivo ini

Para armazenar os Pontos de Restauração foi utilizado a tabela SX5 onde uma tabela de nome “R.” é criada no momento da criação do primeiro Ponto de Restauração e atualizada a cada novo ponto. Os dados dessa tabela são utilizados como referência para a Restauração.

Para testar o processo de “Ponto de Restauração” atualize o Projeto totvs-advpl-naldodj usando o seguinte “link” http://totvs-advpl-naldodj.googlecode.com/svn/trunk/ e efetuando o “SVN Update” da pasta “template”.

Os programas e arquivos relacionados ao “Ponto de Restauração” são:

NDJLIB021.PRG

image

e todos os constantes na pasta “Ponto de Restauração”.

image

Um exemplo de configuração poderá ser obtido a partir do arquivo ndj_rp.ini:

image

Depois de efetuar o “SVN Update” e compilar o Projeto, será necessário, primeiro, executar o programa de Update: U_NDJUPDRP para a preparação do sistema para trabalhar com “Ponto de Restauração”.

Configurar o Parâmetro do SX6 NDJ_RPINI com o caminho para obter-se o arquivo de configuração. Ex.: \ndj_cfg\ndj_rp.ini (será considerado a partir do “RootPath”).

Vale lembrar o que foi dito no post: Protheus :: Junction :: Estendendo o RootPath a partir de diretórios Virtuais (Ligações Simbólicas). Para que o ambiente atual acesse os dados do ambiente de restauração, será necessário uma “Ligação Simbólica” no RootPath do ambiente de “produção” com o “StartPath”, normalmente “\system\”, do ambiente de restauração. e configurá-la no arquivo ini como: RestoreSystemVPath=\system_vlink\. Caso essa chave não seja encontrada no arquivo ini ou a “Ligação Simbólica” não exista, será utilizado o processo de “Cópia de arquivos” utilizando os recursos do SO.

Após o update, e tendo configurado o ambiente para trabalhar com “Ponto de Restauração, entre no sistema e em fórmulas, para a criação do Ponto de Restauração, digite:

StaticCall( NDJRPBKP , TRPSave , "01", "01" , "RP" )

e, para restaurá-lo, digite:

StaticCall( NDJRPBKP , TRPRestore , "01", "01" , "RP" )

Essas funções encontram-se em:

image

teremos algo como:

image

que criará o Ponto de Restauração que podemos consultar:

image

e restaurar executando:

image

após selecionar o ponto a ser “Restaurado”

image

A mensagem informativa de que a restauração ocorreu com sucesso será disponibilizada e, ao clicar no botão OK será feito o “reload” da aplicação recarregando o sistema com o ambiente para o qual a restauração foi efetuada.

image

Em resumo é isso. Para maiores detalhes consulte os arquivos fontes.

A criação de um “Ponto de Restauração” é algo até que simples, mas a decisão de “Restaurar” é sempre complicada. “Restaurar ou Não Restaurar, eis a questão.” Bem, considerando os dois últimos “posts” tenho minhas dúvidas se a “Restauração” seria uma boa, já que posso acessar os arquivos do “Ponto de Restauração” diretamente conforme: Protheus :: Junction :: Estendendo o RootPath a partir de diretórios Virtuais (Ligações Simbólicas) ou Protheus :: Advpl :: Usando Microsoft FoxPro VFP Driver para conexão ODBC (Generic) no totvsdbAccess

Bem, a decisão final é do utilizador. Eis o que há.

[]s

иαldσ dj

Comentários

  1. Fala ae Mestrao Lee!!! Ficou duca esse post, maias uma vez provando que limitação é algo que nao existe no vocabulario.. hehehe... Pode deixar que tambem to preparando um post duca para logo. hehehe... Grande abraço Mestrao e ve se fica inteiro para a volta do feriado!

    ResponderExcluir
  2. Bom dia Naldo, sem duvidas a decisao de se utilizar o ponto de restauracao eh complicada, mesmo assim, tenho certeza que dentro deste "projeto" ha muito codigo util a ser extraido :)
    Obrigado novamente por compartilhar... :)

    ResponderExcluir
  3. *TOTVS é S/A, иαldσ dj Público*

    ...e se você fosse um funcionário TOTVS?

    Como a frase acima seria escrita?

    ...talvez
    TOTVS é S/A, иαldσ dj.. quem é иαldσ dj?

    O jargão marketeiro "LET'S SHARE" tinha que estar em seu blog, pois há uma grande diferença em praticar e idealizar.

    иαldσ dj pratica o LET'S SHARE, TODVS eles.. vendem a idéia.

    Tô cansado de entrar no TDN, procurar uma função e aparecer a frase:
    "Você não tem permissão para acessar esse recurso."

    Aqui é o Black TDN... ou TDN Underground!!
    LET's SHARE, REALLY...

    ResponderExcluir
  4. kkkkkkkkkkkkkkk. Quanta revolta! Faz jus a um provérbio...(next post)

    ResponderExcluir
  5. E, respondendo ao questionamento, faço minhas as palavras dos "Titãns":

    "
    Que não é o que não pode ser que
    Não é o que não pode
    Ser que não é
    O que não pode ser que não
    É o que não
    Pode ser
    Que não
    É

    O que não pode ser que
    Não é o que não pode ser
    Que não é o que
    O que?
    O que?
    O que?
    O que?

    Que não é o que não pode ser
    Que não é o que não pode ser
    Que não é o que não pode ser
    Que não é

    Que não é o que não pode ser
    Que não é o que não pode ser
    Que não é o que não pode ser
    Que não é
    Sei que não é

    O Que não é o que não pode ser que
    Não é o que não pode
    Ser que não é
    O que não pode ser que não
    É o que não
    Pode ser
    Que não
    É

    O que não pode ser que
    Não é o que não pode ser
    O Que não é o que
    O que?
    O que?
    O que?
    O que?

    Que não é o que não pode ser
    Que não é o que não pode ser
    Que não é o que não pode ser
    Que não é
    (2x)

    Pode ser, é
    Pode ser , pode ser , pode ser, pode ser, é
    é

    Que não é o que não pode ser
    Que não é o que não pode ser
    Que não é o que não pode ser
    Que não é"

    ResponderExcluir

Postar um comentário

Postagens mais visitadas