Clipper On Line • Ver Tópico - DBF pra MySQL

DBF pra MySQL

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

 

DBF pra MySQL

Mensagempor JoséQuintas » 21 Set 2019 20:51

Aqui fica bem visível o uso da minha classe.
Apesar de ter que alterar o fonte, fica parecido com o fonte anterior.
Gravação do DBF e do MySQL.

STATIC FUNCTION ImportaFinanceiro( oElement, oNFe, mCliCod, nParcela )

   LOCAL IDFinanceiro, cnMySql := ADOClass():New( AppcnMySqlLocal() )

   SELECT jpfinan
   OrdSetFocus( "numlan" )
   IDFinanceiro := NovoCodigo( "jpfinan->fiNumLan" )
   RecAppend()
   REPLACE ;
      jpfinan->fiNumLan  WITH IDFinanceiro, ;
      jpfinan->fiTipLan  WITH iif( oNFE:Emitente:Cnpj == jpempre->emCnpj, "1", "2" ), ;
      jpfinan->fiNumDoc  WITH oNFE:cNumDoc, ; // 9 digitos
      jpfinan->fiDatEmi  WITH oNFE:DataEmissao, ;
      jpfinan->fiParcela WITH StrZero( nParcela, 3 ), ;
      jpfinan->fiCliFor  WITH mCliCod, ;
      jpfinan->fiSacado  WITH mCliCod, ;
      jpfinan->fiValor   WITH oElement:Valor, ;
      jpfinan->fiDatVen  WITH oElement:Vencimento, ;
      jpfinan->fiDatEmi  WITH oNFE:DataEmissao, ;
      jpfinan->fiPedido  WITH jppedi->pdPedido, ;
      jpfinan->fiInfInc  WITH LogInfo()
   RecUnlock()
   WITH OBJECT cnMySql
      :QueryCreate()
      :QueryAdd( "FINUMLAN", IDFinanceiro )
      :QueryAdd( "FITIPLAN", iif( oNFE:Emitente:Cnpj == jpempre->emCnpj, "1", "2" ) )
      :QueryAdd( "FINUMDOC", oNFE:cNumDoc )
      :QueryAdd( "FIDATEMI", oNFE:DataEmissao )
      ;QueryAdd( "FIPARCELA", StrZero( nParcela, 3 ) )
      :QueryAdd( "FICLIFOR", mCliCod )
      :QueryAdd( "FISACADO", mCliCod )
      ;QueryAdd( "FIVALOR"< oElement:Valor )
      :QueryAdd( "FIDATVEN", oELement:Vencimento )
      :QueryAdd( "FIDATEMI", oNFE:DataEmissao )
      :QueryAdd( "FIPEDIDO", jppedi->PdPedido )
      :QueryAdd( "FIINFINC", LogInfo() )
      :QueryExecuteInsert( "JPFINAN" )
   ENDWITH

   RETURN NIL


cnMySql é o canal de comunicação, o "WhatsApp" com o servidor.
:QueryCreate() e :QueryAdd(), apenas criam uma lista
:QueryExecuteInsert() é a que faz todo trabalho de conversar com o servidor.

Tem mais coisas, além disso, nas rotinas, mas comparando com DBF, seria algo como isto:

// QueryCreate()
aList := {}

// QueryAdd()
AAdd( aList, { "CODIGO", 10 } )
AAdd( aList, { "NOME", "JOSE" } )

//QueryExecuteInsert()
RecLock()
FOR EACH oElement IN aList
   REPLACE &( oElement[ 1 ] ) WITH oElement[ 2 ]
   // FieldPut( FIeldNum( oElement[ 1 ] ), oElement[ 2 ] )
NEXT
RecUnLock()


Inclusive.... olhando agora... talvez mais interessante alterar a gravação de DBF pra usar o mesmo array do MySQL.
Desse jeito, o mesmo fonte serviria pra DBF e MySQL, ao invés de duplicar rotina.
A diferença seria só uma linha pra dbf e uma pra MySQL.

:QueryExecuteInsertDBF()
:QueryExecuteInsert()

Interessante.... vou pensar se vale a pena isso.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

DBF pra MySQL

Mensagempor JoséQuintas » 22 Set 2019 02:26

Não sei se vou usar, mas abaixo a aplicação prática do que mencionei

STATIC FUNCTION ImportaFinanceiro( oElement, oNFe, mCliCod, nParcela )

   LOCAL IDFinanceiro, cnMySql := ADOClass():New( AppcnMySqlLocal() )

   SELECT jpfinan
   OrdSetFocus( "numlan" )
   IDFinanceiro := NovoCodigo( "jpfinan->fiNumLan" )
   WITH OBJECT cnMySql
      :QueryCreate()
      :QueryAdd( "FINUMLAN", IDFinanceiro )
      :QueryAdd( "FITIPLAN", iif( oNFE:Emitente:Cnpj == jpempre->emCnpj, "1", "2" ) )
      :QueryAdd( "FINUMDOC", oNFE:cNumDoc )
      :QueryAdd( "FIDATEMI", oNFE:DataEmissao )
      ;QueryAdd( "FIPARCELA", StrZero( nParcela, 3 ) )
      :QueryAdd( "FICLIFOR", mCliCod )
      :QueryAdd( "FISACADO", mCliCod )
      ;QueryAdd( "FIVALOR"< oElement:Valor )
      :QueryAdd( "FIDATVEN", oELement:Vencimento )
      :QueryAdd( "FIDATEMI", oNFE:DataEmissao )
      :QueryAdd( "FIPEDIDO", jppedi->PdPedido )
      :QueryAdd( "FIINFINC", LogInfo() )
      :QueryDBFExecuteInsert()         /// aqui insere no DBF
      :QueryExecuteInsert( "JPFINAN" )   /// aqui insere no MySQL
   ENDWITH

   RETURN NIL
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

DBF pra MySQL

Mensagempor JoséQuintas » 22 Set 2019 20:22

Esqueci de dizer uma coisa muitíssimo importante:

Não só por causa da compilação -e3 -es2, mas uso SEMPRE o alias.
jpnota->nfNotFis

Então, pra mudança de jpnota pra MySQL, pesquiso em todos os fontes o uso de jpnota->

E o mesmo para cada um dos arquivos.

Já disse várias vezes aqui:

O que mais fazemos é alterar fonte.
Colocar alias parece perda de tempo, mas ganha-se muito tempo depois em alterações.

Tem gente que pra economizar fonte utiliza for/next:

FOR nCont = 1 TO FCount()
   cNome := FieldName( nCont )
   PUBLIC m&cNome
   m&cNome := &cNome
NEXT
...
FOR nCont = 1 TO FCount()
   cNome := FieldName( nCont )
   REPLACE &cNome WITH m&cNome
NEXT


Pode ganhar tempo criando o fonte, mas depois, pra pesquisar uso de campo ou outra coisa... ferrou.

Infelizmente digo o mesmo sobre array.

Gastem bastante tempo criando novos fontes, e aproveitem alterações pra ajustar um pouco de fontes velhos.
Quanto mais fácil alterar, mais tempo irão economizar.

Passar notas pra MySQL.... só pesquisar aonde usa o arquivo de notas JPNOTA.
Se eu usasse um dos esquemas acima.... já era... muita coisa iria passar desapercebida.

Mais outra:

Durante essa "conversão", muitos fontes não tinham a conexão MySQL.
Nem me preocupei com isso.
Na hora de compilar, usando -w3 -es2, o próprio Harbour me avisou sobre as variáveis de conexão, que não existiam.
Foi só ir acrescentando nos fontes que davam erro de compilação.

Vai que decidem fazer igual eu fiz pra migrar pra MySQL.....
É bom saber que tudo isso ajuda a fazer uma migração mais tranquila.

Como eu sempre digo:
Dar uma geral no fonte antes de ir pra uma coisa nova.
Venho fazendo isso há anos... então tudo fica mais tranquilo.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

DBF pra MySQL

Mensagempor JoséQuintas » 23 Set 2019 04:34

Putz, olhem só a possibilidade que acabei inventando com a rotina anterior:

#define GRAVA_DBF          .T.
#define GRAVA_MYSQL      .T.

WITH OBJECT cnMySql
   :QueryCreate()
   :QueryAdd( "ESNUMLAN", "SALDO" )
   :QueryAdd( "ESNUMDOC", "SALDO" )
   :QueryAdd( "ESITEM",   cItem )
   :QueryAdd( "ESOBS",    "SALDO NESTA DATA" )
   :QueryAdd( "ESTIPLAN", iif( oElement[ 1 ] > 0, "2", "1" ) )
   :QueryAdd( "ESDATLAN", dDataLimite - 1 )
   :QueryAdd( "ESNUMDEP", Str( oElement:__EnumIndex, 1 ) )
   :QueryAdd( "ESQTDE",   Abs( oElement[ 1 ] ) )
   :QueryAdd( "ESVALOR",  Abs( oElement[ 2 ] ) / iif( oElement[ 1 ] == 0, 1, oElement[ 1 ] ) )
   IF GRAVA_DBF
      :DBFQueryExecuteInsert()
   ENDIF
   IF GRAVA_MYSQL
      :QueryExecuteInsert( "JPESTOQ" )
   ENDIF
ENDWITH


Acompanhem comigo:

- Alterar as gravações em DBF para a classe
- Acrescentar a linha que grava simultâneo em MySQL
- Alterar tudo pra usar preferencialmente MySQL
- Retirar toda gravação em DBF
- Apagar DBFs

E o principal: prazo de instalação SEMPRE INSTANTÂNEO A CADA ALTERAÇÃO

Não é fantástico !!!
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

DBF pra MySQL

Mensagempor JoséQuintas » 26 Set 2019 09:49

Mais um pra MySQL: PEDIDOS

arquivos.png


Apenas pra curiosidade:

Dos 6 maiores arquivos, 4 passei a salvar no MySQL, isso vai reduzir o tamanho total de DBFs pra menos da metade.

Porque não passei os itens de pedido?
Eles não tem chave única pra referência. Vou criar isso agora, pra no futuro transferir. (talvez semana que vém).

Pois é... tudo indica que de 1GB em DBF vai reduzir pra 50MB...

E se vai sobrar só 50MB... melhor fazer logo tudo de uma vez....
Já pensando nessa idéia de tudo de uma vez.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

DBF pra MySQL

Mensagempor JoséQuintas » 05 Out 2019 21:37

Vixe....
Me empolguei demais, e agora estou mudando de idéia....
Já tem cliente com meio caminho andado, mas talvez refaça....

Por enquanto... como é duplicado em DBF e MySQL, mas com foco no DBF... posso regravar o MySQL à vontade.

Detalhes:

No MySQL só uso campo incremental pra chave, lógico, é o normal e é o melhor uso.
Meu aplicativo é direcionado a chave caractere.
Até agora estava direcionando a conversão pra continuar usando esse campo caractere.... e ia deixar a mudança pra depois no MySQL.
Pois estou pensando em fazer isso ainda no DBF, pra gravar no MYSQL já usando código definitivo, e ao invés de usar minha rotina de numeração, fazer uso do MySQL pra isso, mesmo usando DBF - acho que vai ser mais seguro.
Isso afeta TODO aplicativo, antes mesmo de usar MySQL, e afeta toda conversão, que leva exatamente a estrutura do DBF, o que obriga que o campo chave do MySQL já exista no DBF e que seja numérico.

Pois é....
Agora pensando nas alternativas...
Trata-se inclusive de refazer as conversões que já fiz.
E de deixar tudo pronto pra ser trocado a qualquer hora, esteja como estiver.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

DBF pra MySQL

Mensagempor JoséQuintas » 09 Out 2019 19:37

Desisti de continuar, e voltei atrás.

      :ExecuteCmd( "DROP TABLE IF EXISTS BA_AUTO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS BA_GRUP" )
      :ExecuteCmd( "DROP TABLE IF EXISTS BA_MOVI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTDIARI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTHISTO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTLOTES" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTLANCA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTPLANO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPBAMOVI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPCADAS" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPCLISTA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPCOMISS" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPDOLAR" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPESTOQ" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPFINAN" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPFINANC" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPFORPAG" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPITEM" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPITPED" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPLFISC" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPMDFCAB" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPMDFDET" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPMOTORI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPNOTA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPNUMERO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPPEDI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPPEDIDO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPPRECO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPPRONCM" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPREFCTA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPSENHA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPAGE" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPATI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPINS" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPLOC" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPOPE" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABEL" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTRANSA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTRANSP" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPUF" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPUSRMSG" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPVENDED" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPVEICUL" )
      :ExecuteCmd( "DROP TABLE IF EXISTS RASTREA" )


Não se enganem, NÃO estou zerando tudo.
Isso é só a parte deste mês, e lixos anteriores.
Ainda vão sobrar alguns gigas no MySQL que continuam em uso.

NÃO foi problema com MySQL ou ADO.
É que me empolguei mesmo, agora que estou voltando atrás é que confirmei o quanto exagerei.
Alterar tudo isso no aplicativo AO MESMO TEMPO, foi o que atrapalhou.
Tudo isso, mais estruturas, mais campos chave, e mais outras coisas.

Nenhum problema nos clientes.
TODOS tem coisa que ficou pela metade.
Também não vou ter nenhum problema em voltar atrás.
Lembram? estava duplicando mas funcionando em DBF... se apagar do MySQL... nenhum problema.

Depois da limpeza, fazer UM DE CADA VEZ MESMO.
Me segurar bastante pra me limitar a um DBF por vez.
E também obrigar que clientes atualizem, assim retiro toda parte de apagar tabelas do MySQL.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

DBF pra MySQL

Mensagempor Fernando queiroz » 10 Out 2019 00:10

como terminei a conversão para gráfico, agora chegou a hora da limpeza dos fontes
e partir para -w3 , estou fazendo devagar mas ta ficando 'BUNITO" de ver tudo arrumadinho
depois é partir para um SGBD.
Inclusive estou mudando algumas funções passando parâmetros para facilitar o entendimento
A cabeça já pegou fogo varias vezes :)´ :)´ :)´
HARBOUR 3.2, HWGUI 2.23 B3, SEFAZCLASS, PDFClass, ADO + MariaDB/MySQL, RMChart
Fernando queiroz
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 737
Data de registro: 12 Nov 2014 23:41
Cidade/Estado: Porto Alegre/RS
Curtiu: 12 vezes
Mens.Curtidas: 58 vezes

DBF pra MySQL

Mensagempor JoséQuintas » 12 Out 2019 22:57

Pois é...
Eu sempre posto aqui que primeiro precisa organizar tudo antes de partir pra mudanças, e fiz o oposto kkkk

A próxima versão:
Apagando do MySQL
      :ExecuteCmd( "DROP TABLE IF EXISTS BA_AUTO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS BA_GRUP" )
      :ExecuteCmd( "DROP TABLE IF EXISTS BA_MOVI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTDIARI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTHISTO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTLOTES" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTLANCA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS CTPLANO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPANPMOV" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPBAMOVI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPBARRA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPCADAS" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPCLISTA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPCOMISS" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPDOLAR" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPEMPRE" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPESTOQ" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPFINAN" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPFINANC" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPFORPAG" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPIMPOS" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPITEM" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPITPED" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPLFISC" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPLOGNFE" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPMDFCAB" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPMDFDET" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPMOTORI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPNOTA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPNUMERO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPPEDI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPPEDIDO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPPRECO" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPPRONCM" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPREFCTA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPSENHA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPAGE" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPATI" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPINS" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPLOC" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABANPOPE" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTABEL" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTRANSA" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPTRANSP" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPUF" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPUSRMSG" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPVENDED" )
      :ExecuteCmd( "DROP TABLE IF EXISTS JPVEICUL" )
      :ExecuteCmd( "DROP TABLE IF EXISTS RASTREA" )


e apagando de DBF:

   LOCAL cFile, aList := { ;
      "ba_auto.dbf", ;
      "ba_grup.dbf", ;
      "ba_movi.dbf", ;
      "jpanpage.dbf", ;
      "jpanpins.dbf", ;
      "jpanpope.dbf", ;
      "jpbarra.dbf", ;
      "jpcarcor.dbf", ;
      "jpcep.dbf", ;
      "jpcfop.dbf", ;
      "jpcotaca.dbf", ;
      "jpcotcli.dbf", ;
      "jpcotfor.dbf", ;
      "jpcotpro.dbf", ;
      "jpcte.dbf", ;
      "jpdecret.dbf", ;
      "jpdecret.cdx", ;
      "jpdocrel.dbf", ;
      "jpdocrel .dbf", ; // criou errado
      "jpedicfg.dbf", ;
      "jpfisica.dbf", ;
      "jpibpt.dbf", ;
      "jplicmov.dbf", ;
      "jplogsi.dbf", ;
      "jpnfbase.dbf", ;
      "jpnfeger.dbf", ;
      "jpnfexml.dbf", ;
      "jpnotaca.dbf", ;
      "jpordbar.dbf", ;
      "jpordres.dbf", ;
      "jpordser.dbf", ;
      "jpprehis.dbf", ;
      "jppromix.dbf", ;
      "jpromcab.dbf", ;
      "jpromdet.dbf", ;
      "jptexto.dbf", ;
      "jpvvdem.dbf", ;
      "jpvvfin.dbf", ;
      "nfbase.dbf", ;
      "rastrea.dbf" }

   FOR EACH cFile IN aList
      IF File( cFile )
         fErase( cFile )
      ENDIF
   NEXT
   aList := Directory( "tmp*.dbf" )
   FOR EACH cFile IN aList
      fErase( cFile[ F_NAME ] )
   NEXT
   IF ! AppConexao() == NIL
      IF File( "jpreguso.dbf" )
         fErase( "jpreguso.dbf" )
      ENDIF
   ENDIF


Na prática restaram alguns clientes com DBF de aplicativo específico.
Pra esses, que não tem MySQL, o log do aplicativo continua em DBF.

Para os DBFs, comparei as pastas das empresas.

#include "directry.ch"
#include "inkey.ch"

PROCEDURE Main

   LOCAL aList := {}, cPath, aDbfList, oDbf, nPos, oFile

   CLS
   FOR EACH cPath IN ;
      { "assesor", "carbolub", "cicuto", "cordeiro", "crispetrol", ;
        "dricar", "gargantua", "locafacil", "lubrivan", "maringa", ;
        "peaton", "toppetro", "unifila", "waripaer" }
      aDBFList := Directory( "d:\jpa\" + cPath + "\*.dbf" )
      FOR EACH oDBF IN aDBFList
         IF ( nPos := ASCan( aList, { | e | e[ 1 ] == Upper( oDBF[ F_NAME ] ) } ) ) == 0
            AAdd( aList, { Upper( oDBF[ F_NAME ] ), 0, "" } )
            nPos := Len( aList )
         ENDIF
         aList[ nPos, 2 ] += 1
         aList[ nPos, 3 ] += cPath + ","
      NEXT
   NEXT
   FOR EACH oFile IN aList
      IF oFile[ 2 ] != 14
         ? oFile[ 1 ], oFile[ 2 ], oFile[ 3 ]
      ENDIF
   NEXT
   ? "Fim"
   Inkey(0)

   RETURN


Agora fazer algo parecido pra comparar as bases MySQL, pra ver se tem lixo em alguma.

Como é o mesmo aplicativo em todas, mesmo que não usem tudo, pelo menos tem que existir as mesmas bases em DBF e MySQL.
No geral, conversões que eu tinha deixado preparado, ou módulos desativados que não apaguei arquivos antes.

Pois é... agora seguindo meus próprios conselhos de organizar tudo primeiro kkkk

E como a versão apaga até tabelas do MySQL...
Talvez obrigar a troca de versão primeiro. em todos, e depois retirar tudo isso de apagar do MySQL, já que vão entrar tabelas oficiais depois.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

DBF pra MySQL

Mensagempor JoséQuintas » 25 Nov 2019 10:04

Só pro post não ficar sem fim....
Tá em andamento.

Hoje alterando um fluxo de caixa, aqui dá uma boa idéia de DBF e ADO/MySQL

   mTempFile := TempFileArray( 2 )
   IF m_DeAte == 1
      COPY TO ( mTempFile[ 1 ] ) FIELDS idFinan, fiDatVen, fiTipLan, fiNumDoc, fiParcela, ;
         fiDatEmi, fiCliFor, fiValor, fiObs FOR ;
         Empty( jpfinan->fiDatPag ) .AND. Empty( jpfinan->fiDatCan ) ;
         .AND. GrafProc()
   ELSE
      COPY TO ( mTempFile[ 1 ] ) FIELDS idFinan, fiDatVen, fiTipLan, fiNumDoc, fiParcela, ;
         fiDatEmi, fiCliFor, fiValor, fiObs FOR ;
         jpfinan->fiDatVen >= m_Datai .AND. jpfinan->fiDatVen <= m_Dataf ;
         .AND. Empty( jpfinan->fiDatPag ) .AND. Empty( jpfinan->fiDatCan ) ;
         .AND. GrafProc()
   ENDIF
   SELECT 0
   USE ( mTempFile[ 1 ] ) NEW ALIAS temp
   INDEX ON Dtos( temp->fiDatVen ) + temp->fiTipLan + temp->fiNumDoc + temp->fiParcela to ( mTempFile[ 2 ] )
   SELECT temp
   GOTO TOP
   DO WHILE nKey != K_ESC .AND. ! Eof()


Como já comentei, o SQL/ADO é como trabalhar com arquivos temporários.
Neste fonte fica bem nítida a mudança.

      cSql := "SELECT IDFINAN, FIDATVEN, FITIPLAN, FINUMDOC, FIPARCELA, FIDATEMI, FICLIFOR, FIVALOR, FIOBS " + ;
         "FROM JPFINAN " + ;
         "WHERE ISEMPTY( FIDATPAG ) AND ISEMPTY( FIDATCAN )"
      IF m_DeAte == 2
         cSql += " AND FIDATVEN BETWEEN " + DateSql( m_Datai ) + " AND " + DateSql( m_Dataf )
      ENDIF
      cSql += " ORDER BY FIDATVEN, FITIPLAN, FINUMDOC, FIPARCELA"
      Temporario := Conexao:Execute( cSql )
      DO WHILE nKey != K_ESC .AND. ! Temporario:Eof()


Isso acima é sem minha classe, ADO puro.
Além de menos fonte, fica muito mais rápido.

Nota: deixou de ser teste, agora é uso prático mesmo.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Anterior



Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Google Adsense [Bot] e 17 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro