Clipper On Line • Ver Tópico - ODBC conecta DBF e nao respeita RLOCK()/FLOCK() !
ODBC conecta DBF e nao respeita RLOCK()/FLOCK() !
por ANDRIL » 06 Out 2015 21:57
Pessoal, criei uma conexão no ODBC para acessar meus DBFs, funcionou.
O problema é que se defino esta conexão no ODBC como EXCLUSIVE eu só posso abrir o DBF em modo EXCLUSIVE (meu DBF fica aberto o tempo todo como SHARED para que todas as máquinas da rede possam acessá-lo e não posso fechá-lo).
Se retiro o EXCLUSIVE do ODBC, ele não respeita o RLOCK e FLOCK quando bloqueio o DBF, por exemplo, aplico o RLOCK em um registro e executo a conexão e query no ODBC e ele altera o registro bloqueado pelo programa em harbour/clipper.
Resumindo, há alguma forma do ODBC trabalhar respeitando o travamento dos DBF feito pelo Harbour/Clipper, algum tipo de conectionstring que habilite este serviço.
O script que roda o ODBC é em PHP.
por JoséQuintas » 07 Out 2015 09:49
O primeiro ponto é que o driver ODBC e o driver do Harbour sejam compatíveis, incluindo o que se refere a bloqueio e índices.
Quando usei ADS, configurei o ODBC pra CDX compatível, e no Clipper/Harbour o equivalente a SIXCDX, e no Harbour como adicional o bloqueio também compatível.
O ODBC trata todos os arquivos como uma base de dados, então é como se todos os DBFs estivessem abertos por ele.
No ODBC usava uma configuração única de modo compartilhado (nem lembro se existia modo exclusivo).
Começa por aí:
drivers compatíveis a nível de dbt/fpt, índices e bloqueio de registro
No ADS eu usava esta string no VB:
Case "ADSLOCAL"
cString = "Provider=Advantage.OLEDB.1;" & _
"Show Deleted Records in DBF Tables with Advantage=False;" & _
"Data Source=" & Sistema.PathDefault & ";Advantage Server Type=ADS_Local_Server;" & _
"TableType=ADS_CDX;Security Mode=ADS_IGNORERIGHTS;" & _
"Lock Mode=Compatible;" & _
"Use NULL values in DBF Tables with Advantage=True;" & _
Mens.Curtidas: 765 vezes
por ANDRIL » 07 Out 2015 19:26
JoséQuintas escreveu: O primeiro ponto é que o driver ODBC e o driver do Harbour sejam compatíveis
Seguindo algumas sugestões tentei trabalhar com formato DBF/CDX no ODBC porem não consegui, exige o drive do FOXPRO e a M$ deixou de disponibilizá-lo.
Se alguem tiver este drive ODBC e puder me passar para fazer os testes agradeço.
JoséQuintas escreveu: drivers compatíveis a nível de dbt/fpt, índices e bloqueio de registro
No caso se meu sistema harbour utilizar DBFCDX e o ODBC estiver configurado para esse índice, será que o bloqueio de registro rLock() e arquivo fLock() serão respeitados pelo ODBC?
JoséQuintas escreveu: "Lock Mode=Compatible;"
Veja, eu só tenho o ODBC no PC, o ADO, ADS, OLEDB etc nem faço idéia, tem como colocar este parâmetro para uso na string de conexão do ODBC?
Acho que isso resolveria meu problema.
Realmente nunca mexi com nada desse tipo e agora estou praticamente "preso" ao descobrir o problema de travamento o que pode comprometer todo o sistema.
por JoséQuintas » 07 Out 2015 19:53
Acredito que existam várias formas de acessar DBFs pelo php, não dá pra saber qual usou.
Supondo que tenha usado ODBC, existem diversos ODBCs, também não dá pra saber qual está usando.
Isso não é padrão, só quem usa igual é que vai saber responder, e pra isso vão precisar de mais informações.
por ANDRIL » 21 Ago 2017 01:55
Continuo precisando fazer as seguintes operações via ODBC e não consigo:
1-Localizar um produto via SELECT;
2-Bloquear o registro já que não posso bloquear a tabela porque estará aberta compartilhada;
3-Fazer a alteração do conteúdo do campo;
4-Liberar a tabela
Teria algum exemplo dessas etapas usando o drive DBF para odbc?
por JoséQuintas » 21 Ago 2017 08:49
Esqueça estilo DBF.
Em servidor SQL, NÃO existem dois terminais alterando ao mesmo tempo.
O servidor vai processar os comandos de um terminal por vez.
Atualizar um campo?
UPDATE TABELA SET CAMPO=VALOR WHERE CODIGO=10
Já pesquisou e atualizou.
No momento da atualização, o servidor vai estar processando ESTE comando DESTE terminal.
E aí pergunto: travar pra que?
Imagine um sistema utilizado pelo Brasil inteiro.
Vai bloquear um registro e impedir o Brasil inteiro de atualizar até que o usuário termine?
Se tem dois usuários alterando um cadastro, paciência, o último que gravar é o que fica.
Se um usuário alterar as 4:00 horas e o outro alterar as 05:00 horas, não é o das 05:00 horas que fica?
Porque precisa ser diferente se a diferença de tempo for um milésimo de segundo?
Mesmo em DBF, deveria ser assim.
REPLACE estoque WITH estoque + 1
Pra que esses SKIP 0 aparentemente inúteis?
Ué... se o registro estava bloqueado, significa que só podiam estar alterando/atualizando.
Se estavam alterando/atualizando, o conteúdo modificou.
Se o conteúdo modificou, um SKIP 0 vai atualizar o cache local.
Após o replace, um SKIP 0 vai garantir que o conteúdo foi salvo.
E uma vez salvo, pode ser liberado pra acesso por outro terminal.
Não precisa ser assim:
Em SQL, um terminal está alterando e o outro exclui:
UPDATE tabela SET CAMPO=CONTEUDO WHERE CODIGO=1
Se o código não existe mais, não vai ser atualizado.
Nenhum erro no aplicativo.
Ah... mas se está alterando não era pra deixar excluir....
Se um usuário altera as 04:00, e o outro exclui as 05:00, não é pra excluir?
Se um usuário exclui as 04:00 horas, o outro consegue alterar as 05:00 horas?
Então... mesma coisa se forem milésimos de segundo de diferença....
Em DBF: antes de atualizar, outro SEEK, igual o SQL faz, e pronto, avisa o usuário que não existe mais.
Dá pra aprender com SQL, e ver que em DBF acostumamos errado.
por ANDRIL » 21 Ago 2017 12:17
Concordo em partes com o exposto acima, mais agora preciso integrar 2 sistemas, um em Harbour (DBF) e outro PHP (ODBC) para gerenciar o estoque.
No Harbour fiz um teste simples, abri a tabela de produto ativei o bloqueio no primeiro registro. Outros programas em Harbour acusam que o registro esta bloqueado, ok. Agora se uso um UPDATE via ODBC no PHP ele altera o conteúdo, ou seja, enquanto outros estão alterado o estoque ele bagunça o resultado. As operações de bloqueios são rápidas mais não posso correr o risco justamente no controle de estoque.
Em consultas em outros SQL tem algumas opções como
UPDATE TABELA WITH(ROWLOCK) SET CAMPO = 'NOVO_VALOR' WHERE CAMPO1 = 9
Só que não consigo.
por JoséQuintas » 21 Ago 2017 13:19
O Advantage seque o padrão SQL Server, não sei dizer quanto aos comandos exatos pra bloqueio.
Quanto à string:
Também não sei dizer quanto a PHP, porque não uso.
Outra opção seria o saldo de estoque estar em MySQL ou algo assim, e atualizar o saldo no MySQl tanto em Harbour quanto em PHP.
E usar ODBC nos dois pra isso.
por JoséQuintas » 21 Ago 2017 13:23
A título de curiosidade, é só porque estou com a mão na massa, acabei de criar esta rotina... se é que dá pra chamar de rotina pela simplicidade.... rs
STATIC FUNCTION ApagaLogAntigo( dDataLimite )
cnMySql:ExecuteCmd( "DELETE FROM JPREGUSO WHERE RUINFINC < " + DateSql( dDataLimite ) )
Conforme a gente vai criando rotinas, vai ficando mais simples usar ADO + MySql.
por ANDRIL » 21 Ago 2017 15:08
JoséQuintas escreveu: Outra opção seria o saldo de estoque estar em MySQL ou algo assim, e atualizar o saldo no MySQl tanto em Harbour quanto em PHP.
Não tenho como mudar o controle de estoque de DBF para Mysql são diversas funções de acesso ao estoque.
Pelo jeito vou ter que criar meu próprio semáfaro.
por JoséQuintas » 21 Ago 2017 16:02
A intenção é continuar com o aplicativo em Harbour?
Eu tenho basicamente 1 (uma) função pra atualizar estoque no aplicativo.
E 1 (uma) função pro pedido atualizar estoque.
E atualizo estoque em vários locais, chamando essas funções.
Algo como: BaixaPedido( pedido, 1 ) e BaixaPedido( pedido, -1 ), pra baixar normal ou anular baixa anterior
Tem pedido que baixa estoque na confirmação, tem pedido que baixa na emissão de nota, tem pedido que não baixa estoque.
Ao centralizar a rotina de baixa, eu garanto que todos os locais de fonte vão tratar do jeito que deve ser, não correndo o risco de um fazer diferente do outro.