Página 28 de 35

Meu modo de trabalho

Enviado: 13 Set 2021 17:19
por JoséQuintas
jpa.png
Uia, no aplicativo de uso geral, carregando a versão de hoje.

O que ela tem de especial ???
jpa2.png
Senhas no MySQL !!!

Falta ajustar a configuração de senhas....
Por enquanto fica valendo somente o que já existe cadastrado.
E somente 83KB de fora do MySQL.

JPCT* e JPCONTABIL, se aparecerem no terminal do usuário sem problemas, vão estar sempre vazios.
Os demais ainda preciso verificar, pode ser resto de coisas fora de uso.
ACHO que o que vai dar mais trabalho é o JPEMPRESA, porque ficam todos os dados da empresa disponíveis o tempo todo.
Talvez substituir por uma classe contendo tudo, assim pelo menos vai ser uma única variável.

Meu modo de trabalho

Enviado: 13 Set 2021 17:34
por JoséQuintas
usuarios.png
Agora ajustar este programa.
Lembram dele ?

Dá pra configurar acesso de cada usuário/grupo a cada opção.
Aqui já pegando informação do MySQL, mas não está totalmente ajustado.

Meu modo de trabalho

Enviado: 13 Set 2021 17:40
por JoséQuintas

Código: Selecionar todos

STATIC FUNCTION Update0913()

   LOCAL cnSQL := ADOClass():New( AppConexao() )

   IF ! File( "jpsenha.dbf" )
      RETURN Nil
   ENDIF

   IF ! AbreArquivos( "jpsenha" )
      RETURN Nil
   ENDIF

   DO WHILE ! Eof()
      WITH OBJECT cnSQL
         :QueryCreate()
         :QueryAdd( "PWTYPE", jpsenha->pwType )
         :QueryAdd( "PWFIRST", jpsenha->pwFirst )
         :QueryAdd( "PWLAST", jpsenha->pwLast )
         :QueryAdd( "PWINFINC", jpsenha->pwInfInc )
         :QueryAdd( "PWINFALT", jpsenha->pwInfAlt )
         :QueryExecuteInsert( "JPSENHA" )
      ENDWITH
      RecLock()
      DELETE
      SKIP
   ENDDO
   CLOSE DATABASES
   USE ( "jpsenha" ) EXCLUSIVE
   PACK
   CLOSE DATABASES

   RETURN Nil
A rotina de atualização com a data de hoje, grava tudo no MySQL e já apaga do DBF.
O PACK foi pra minha curiosidade, pra reduzir o tamanho do DBF, e ver o que sobrou.
Na prática acho que vou deixar como backup, pelo menos por enquanto.

Meu modo de trabalho

Enviado: 13 Set 2021 17:49
por JoséQuintas
Uia...

Código: Selecionar todos

              GOTO TOP
               nQtd := 0
               DO WHILE ! Eof()
                  IF jpsenha->pwType == "M" .AND. pw_Descriptografa( jpsenha->pwLast ) == private_cUser
                     nQtd += 1
                  ENDIF
                  SKIP
               ENDDO
               IF nQtd != 0
                  MsgExclamation( "Tem usuários neste grupo, não pode ser excluído" )
                  LOOP
               ENDIF
Usando minha rotina velha de ADO:

Código: Selecionar todos

IF ADORecCount( "JPSENHA", "PWTYPE='M' AND PWLAST=" + StringSQL( private_User ) ) != 0
   MsgExclamation( "Tem usuários neste grupo, não pode ser excluído" )
   LOOP
ENDIF
Ou a rotina nova:

Código: Selecionar todos

IF cnSQL:ReturnValue( "SELECT COUNT(*) AS QTD FROM JPSENHA WHERE PWTYPE='M' AND PWLAST=" + StringSQL( private_User ) ) != 0
   MsgExclamation( "Tem usuários neste grupo, não pode ser excluído" )
   LOOP
ENDIF

Meu modo de trabalho

Enviado: 13 Set 2021 19:47
por JoséQuintas
Errei no anterior, faltou a criptografia.
Isso não vou deixar no servidor, senão vai ficar visível.

Meu modo de trabalho

Enviado: 14 Set 2021 00:34
por JoséQuintas
arquivos.png
Fiz um PACK em todos.
Falta 50kb agora.

Meu modo de trabalho

Enviado: 14 Set 2021 01:11
por alxsts
Olá!

No velho DBF, que não controla integridade referencial a saída era contar ou dar seek pra ver se podia deletar um registro pai sem deixar registros órfãos...

Em um banco relacional, é possível usar o controle de integridade referencial:

Código: Selecionar todos

/*
        Alexandre Santos
        Compilar: Hbmk2 teste hbwin.hbc
*/


FUNCTION Teste()

   LOCAL oCn, oRs, cCnString
   LOCAL bErr := ErrorBlock( {|e| Break(e) } ), oErr

   REQUEST HB_LANG_PT
   REQUEST HB_CODEPAGE_PTISO

   HB_CDPSELECT("PTISO")
   CLS

   Begin Sequence
      /*
           Ajuste aqui a connection string conforme o banco
           Ou pequise aqui...: https://www.connectionstrings.com/
      */

      //cCnString := "DRIVER={MariaDB ODBC 3.1 Driver};TCPIP=1;SERVER=serverjpa;Database=tatu;UID=tatu;PWD=tatu;PORT=3306"
      cCnString := "DRIVER={MariaDB ODBC 3.1 Driver};TCPIP=1;SERVER=localhost;Database=test;UID=root;PWD=root;PORT=3306"

      oCn := win_OleCreateObject("ADODB.Connection")

      oCn:ConnectionString := cCnString
      oCn:CursorLocation := 3

      oCn:open()

      oRs := oCn:Execute( "CREATE TABLE tbGroup (group_id INT NOT NULL, PRIMARY KEY (group_id));" )

      oRs := oCn:Execute( "CREATE TABLE tbGroupMember (groupMember_id INT NOT NULL, group_id INT NOT NULL, " + ;
                          "PRIMARY KEY(group_id, GroupMember_id), " + ;
                          "FOREIGN KEY(group_id) REFERENCES tbGroup(group_id));" )

      oRs := oCn:Execute( "INSERT INTO tbGroup ( group_id ) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);" )

      oRs := oCn:Execute( "INSERT INTO tbGroupMember (groupMember_id, group_id) VALUES " + ;
                          "(171, 1), (59, 1), (127, 1), (289, 2), (127, 2), (79, 3), (127, 3), (59, 3);" )

      oRs := oCn:Execute( "delete from tbGroup where group_Id = 1;" )  // o grupo 1 tem filhos e não pode ser excluído

   Recover Using oErr
      With Object oErr
         If At( "Cannot delete or update a parent row: a foreign key constraint fails", :description ) > 0
            hb_Alert( "Tem usuários neste grupo, não pode ser excluído" )
         Endif
      End With
   Always
      oRs := oCn:Execute( "drop TABLE tbGroupMember" )
      oRs := oCn:Execute( "drop TABLE tbGroup" )

      If oRs != NIL
         oRs:close()
      Endif

      If oCn != NIL
         oCn:close()
      Endif

      oCn := NIL
      oRs := NIL

      ErrorBlock( bErr )
   End Sequence

RETURN NIL
//------------------------------------------------------------------------------

Meu modo de trabalho

Enviado: 14 Set 2021 02:30
por JoséQuintas
jpa.png
Tá diminuindo.


Sobre isso de chave estrangeira, vou acabar usando, mas por enquanto ainda não.
Isso vai exigir alguns cuidados a mais, inclusive com backup.
Provavelmente desligar o relacionamento no retorno do backup, porque se restaurar fora de ordem, vai dar falta do que ainda não restaurou.
E pra base já existente, podem existir falhas de relacionamento.

Sobre as procedures/functions ref. senhas.... removi todas.
Mostrar o esquema de senhas de acesso pode ser um risco à segurança, achei melhor remover tudo, e deixar só no EXE.

Meu modo de trabalho

Enviado: 14 Set 2021 02:33
por JoséQuintas
jpa.png
jpa.png (9.78 KiB) Exibido 67317 vezes
Sobre o EXE.
Como já comentei por aqui, deve ficar sempre em torno de 2.2MB.
Se reduzir (quando remover conversões) vai ser pouco.

Meu modo de trabalho

Enviado: 19 Set 2021 11:00
por JoséQuintas
Durante os testes, reparei muitos arquivos sendo salvos em backup, referente a um dos clientes.
São estes arquivos:

Código: Selecionar todos

14/04/2015  16:56             1.000 OB000095.TXT
23/07/2015  11:49             1.000 OB000096.TXT
30/07/2015  15:57             1.000 OB000098.TXT
02/07/2021  15:20               500 OB000100.TXT
19/12/2018  10:34               500 OB000102.TXT
12/07/2016  15:47             1.000 OB000103.TXT
06/07/2020  16:19               500 OB000105.TXT
24/02/2017  13:01               500 OB000106.TXT
10/06/2021  14:08               500 OB000108.TXT
16/11/2017  14:42             1.000 OB000111.TXT
02/08/2021  13:06               500 OB000114.TXT
05/02/2019  13:36               500 OB000117.TXT
25/08/2020  15:24               500 OB000121.TXT
10/06/2019  12:41             1.000 OB000123.TXT
26/11/2019  12:00               500 OB000125.TXT
10/06/2021  16:58               500 OB000126.TXT
25/03/2021  16:59               500 OB000127.TXT
24/03/2020  13:46             1.000 OB000128.TXT
16/07/2020  14:03               500 OB000129.TXT
17/07/2020  15:54             1.000 OB000130.TXT
15/12/2020  13:22             1.000 OB000131.TXT
04/01/2021  15:53             1.000 OB000132.TXT
18/02/2021  14:32               500 OB000133.TXT
20/05/2021  13:14               500 OB000134.TXT
28/07/2011  15:49               607 P0560.MEM
07/12/2012  14:03                74 P0600.MEM
10/11/2015  10:33             7.924 PNOT0200.TXT
16/09/2021  00:18    <DIR>          TEMP
16/09/2021  00:18    <DIR>          XML
             103 arquivo(s)     48.179.895 bytes
É um caso específico, onde tem observações fixas para clientes, e uso arquivo em disco OB*.TXT.
Já acrescentei esta rotina no aplicativo:

Código: Selecionar todos

STATIC FUNCTION Update0919()

   LOCAL aFile, aList, nIdCadastro, cFile, cTexto
   LOCAL cnSQL := ADOLocal()

   IF Len( Directory( "ob*.txt" ) ) == 0
      RETURN Nil
   ENDIF
   aList := Directory( "ob*.txt" )
   FOR EACH aFile IN aList
      cFile := aFile[ F_NAME ]
      cFile := Substr( cFile, 1, At( ".", cFile ) - 1 )
      nIdCadastro := Val( Substr( cFile, 4 ) )
      cTexto := MemoRead( aFile[ F_NAME ] )
      IF nIdCadastro != 0 .AND. ! Empty( cTexto )
         cnSQL:ExecuteCmd( "INSERT INTO JPTABINFADI ( INFADICADASTRO, INFADITEXTO ) VALUES ( " + ;
            NumberSQL( nIdCadastro ) + ", " + StringSQL( cTexto ) )
         fErase( aFile[ F_NAME ] )
      ENDIF
   NEXT

   RETURN Nil
Estou transferindo o que era em disco, pra uma tabela MySQL.
Para o aplicativo será simples, um SELECT pra buscar se existe algo gravado, e um INSERT/UPDATE pra salvar.
Trocentos arquivos a menos no disco !!!!

Meu modo de trabalho

Enviado: 19 Set 2021 11:02
por JoséQuintas
-2147217900 [MySQL][ODBC 5.3(a) Driver][mysqld-5.5.5-10.6.3-MariaDB]You have an error in your SQL syntax;
check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
Esqueci de fechar os parêntesis.... rs

Meu modo de trabalho

Enviado: 19 Set 2021 11:13
por JoséQuintas
infadic.png
Pronto, eliminados trocentos arquivos da pasta.
Tinha esquecido desse caso "diferente".

Meu modo de trabalho

Enviado: 19 Set 2021 11:45
por JoséQuintas

Código: Selecionar todos

      IF mUsaObsAnterior
         IF ! Empty( mInfAdic )
            WITH OBJECT cnSQL
               IF ADORecCount( "JPTABINFADI", "INFADICADASTRO=" + NumberSQL( nIdCadastro ) ) == 0
                  :ExecuteCmd( "INSERT INTO JPTABINFADI ( INFADICADASTRO, INFADITEXTO ) VALUES" + ;
                     "( " + NumberSQL( nIdCadastro ) + ", " + StringSQL( mInfAdic ) + " )" )
               ELSE
                  :ExecuteCmd( "UPDATE JPTABINFADI SET INFADITEXTO=" + StringSQL( mInfAdic ) + ;
                     " WHERE INFADICADASTRO=" + NumberSQL( nIdCadastro ) )
               ENDIF
            ENDWITH
         ENDIF
      ENDIF
Pra quem ainda fica imaginando e ainda não entendeu....
Aonde vou salvar? em JPTABINFADI.
Se não tem cadastrado, envio comando incluir

Código: Selecionar todos

INSERT INTO JPTABINFADI ( INFADICADASTRO, INFADITEXTO ) VALUES ( 999, "xxxx" )
Se já tem cadastrado, é só atualizar.

Código: Selecionar todos

UPDATE JPTABINFADI SET INFADITEXTO="xxxx" WHERE INFADICADASTRO=999
O aplicativo não precisa USE, SELECT, SET INDEX, SET ORDER, RLOCK, NADA, porque ele não mexe no arquivo, quem mexe é o servidor.
E o servidor recebeu toda informação detalhada que precisava sobre aonde gravar.

Meu modo de trabalho

Enviado: 19 Set 2021 15:57
por JoséQuintas
Pra quem não percebeu, o arquivo de senhas, reponsável por todo acesso, seja DBF ou MYSQL, estava em DBF até a semana passada.
Em vários clientes ainda está, enquanto eles não atualizarem o aplicativo.

Código: Selecionar todos

30/07/2021  23:58               579 jpcontabil.DBF
30/07/2021  23:58             6.723 jpctconta.DBF
30/07/2021  23:58               323 jpctlotes.DBF
07/09/2020  22:56             5.335 jpempresa.dbf
Agora restam esses.

Provavelmente elimine ainda o JPCTLOTES.DBF, que tem uso simples.
O JPEMPRE.DBF está disponível o tempo todo. Ao alterar pra MySQL... vai precisar muita alteração.
Os outros dois, foi o que sobrou de toda contabilidade, precisa alterar todo aplicativo de contabilidade, praticamente reescrever muita coisa.

Talvez elimine o JPCTLOTES primeiro, por ser mais simples e pouco uso.
Depois, o JPEMPRE.DBF, pra eliminar a necessidade de DBF - os da contabilidade podem ficar vazios aonde não usa, sem problema.

Lembrando:

Além desse aplicativo geral, tem o da imobiliária que usa muito DBF ainda, e talvez uns 30 usuários.
Preciso passar lá pra reindexar, porque tá ficando lento por ter muita coisa excluída.
De um modo geral, foi o primeiro lugar aonde usei MySQL, mas só transferi arquivos com mais de 1 milhão de registros.
Tem muito ainda a transferir para MySQL.... não tem a ver com o outro aplicativo geral.

Meu modo de trabalho

Enviado: 20 Set 2021 13:01
por JoséQuintas
contabilidadesql.png
um único arquivo com um único registro.
Tudo isso de fonte alterado.
E tudo isso se refere a menos de um dia de trabalho.
E ainda não terminei....

Acabei criando funções pra variáveis estáticas de maior uso, pra ficar disponível no aplicativo inteiro.
AppAnoBase() e AppFechamento().

As demais, pegar conforme o uso, e ainda ajustando.