Clipper On Line • Ver Tópico - Criar Índice CDX em Modo Compartilhado

Criar Índice CDX em Modo Compartilhado

Discussão sobre Banco de Dados e RDDs para Clipper/[x]Harbour.

Moderador: Moderadores

 

Criar Índice CDX em Modo Compartilhado

Mensagempor Dri » 07 Out 2006 08:03

Hi!

People, gostaria de uma confirmação: é verdade que se eu criar índices CDX, desde que o nome do arquivo de índice não seja o mesmo nome do arquivo DBF, posso fazê-lo abrindo o arquivo em modo compartilhado (SHARED) e sem bloquear o arquivo (sem usar o FLOCK())?

Se for verdade, será possível criar índices temporários à vontade nas aplicações que rodam em rede!

Brigadinha!
Abraços!
Dri (F)
Dri
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 28
Data de registro: 06 Set 2004 20:09
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Mensagempor momente » 07 Out 2006 17:48

Dri,

Se entendi sua pergunta, seria pra criar um arquivo de indice temporário?

Se for isso! Aconselho criar um dbf temporario e depois um indice para ele, pois imagine se alguem estiver incluindo um registro no exato momento que vc estiver criando o indice, eu acho (digo eu acho!) que vai dar alguma coisa errada! Acredito que este indice não vai estar correto! Eu particularmente nunca fiz desta maneira.

Valeu! :)Pos
Rogerio L. Momenté
Nada é tão perfeito que não possamos melhorar.
Nunca se explique. Seus amigos não precisam e seus inimigos não vão acreditar.
www.looksystem.com.br
Avatar de usuário

momente
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 496
Data de registro: 03 Mar 2005 11:53
Cidade/Estado: São Carlos-SP
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Mensagempor Dri » 07 Out 2006 18:27

Hi, Momente!

Sim, é pra índice temporário.

É que estou com um problema... Como criar o índice temporário a partir de um arquivo que fica sempre em uso na rede?
E se optar pelo arquivo temporário, aí além de criar o índice, que já demora um pouco, imagine ainda ter que primeiro criar o arquivo...
Abraços!
Dri (F)
Dri
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 28
Data de registro: 06 Set 2004 20:09
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Mensagempor Maligno » 08 Out 2006 05:08

Dri escreveu:É que estou com um problema... Como criar o índice temporário a partir de um arquivo que fica sempre em uso na rede?

Existe algum bom motivo que te impeça de tornar permanente esse índice temporário? Se a chave de indexação não mudar,...

[]'s
Maligno
http://www.buzinello.com/prg
Avatar de usuário

Maligno
Membro Master

Membro Master
 
Mensagens: 6390
Data de registro: 06 Jul 2004 01:40
Cidade/Estado: Londrina/PR
Curtiu: 1 vez
Mens.Curtidas: 14 vezes

Mensagempor Dri » 08 Out 2006 07:31

Hi, Maligno!

Maligno, é difícil afirmar para você as coisas! hihihihihi
Meus conhecimentos são reles comparados aos seus e não me permite isto.
Então vou lhe responder assim: "Sabe, Maligno, eu acho (toda mulher inteligente é cheia de dúvidas... eu acho!) que existe um bom motivo para criar índices temporários!"... rsrsrsrsrs

Chega de embromação!

É o seguinte: Há uma consulta onde um dos parâmetros é um campo que o usuário informará uma partícula do nome. Ao iniciar a consulta, seriam obtidos todos os clientes com aquela partícula do nome e estes exibidos num browser.
Particularmente, pensei em criar um índice temporário montando-o com o operador "$".
Testei e funciona, mas aí ficou a dúvida quanto a criar o índice se o arquivo já está em uso por outro usuário, e para tal, eu teria que bloquear este arquivo ou então abri-lo em modo exclusivo.

E então, Maligno? Ou terei que mudar de estratégia?

Obrigada!
Abraços!
Dri (F)
Dri
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 28
Data de registro: 06 Set 2004 20:09
Curtiu: 0 vez
Mens.Curtidas: 0 vez

sx_WildSeek

Mensagempor Maligno » 08 Out 2006 11:39

É o seguinte: Há uma consulta onde um dos parâmetros é um campo que o usuário informará uma partícula do nome. Ao iniciar a consulta, seriam obtidos todos os clientes com aquela partícula do nome e estes exibidos num browser.
Particularmente, pensei em criar um índice temporário montando-o com o operador "$".
Testei e funciona, mas aí ficou a dúvida quanto a criar o índice se o arquivo já está em uso por outro usuário, e para tal, eu teria que bloquear este arquivo ou então abri-lo em modo exclusivo.

E então, Maligno? Ou terei que mudar de estratégia?

Bom, acho que nesse caso talvez você nem precise utilizar um índice temporário. O RDD CDX (estou falando da LIB SIX) possui uma função chamada sx_WildSeek(), que permite pesquisar por partes de nomes. Exemplo:

Suponhamos que você tenha no seu cadastro:

ABC IND. DE APARELHOS DE GINASTICA LTDA
AUTO MOLAS SANTISTA LTDA
BAR E LANCHONETE PAULISTA LTDA
RECUPERADORA SANTARÉM LTDA
OFICINA DO TOLEDO S/A
BOAVISTA COMERCIO DE CEREAIS LTDA

sx_WildSeek("*ISTA",.F.)
while Found()
   ? NOME
   sx_WildSeek("*ISTA",.T.)
end

Isso resultará em:
AUTO MOLAS SANTISTA LTDA
BAR E LANCHONETE PAULISTA LTDA
BOAVISTA COMERCIO DE CEREAIS LTDA

sx_WildSeek("*INA",.F.)
while Found()
   ? NOME
   sx_WildSeek("*INA",.T.)
end

Isso resultará em:
ABC IND. DE APARELHOS DE GINASTICA LTDA
OFICINA DO TOLEDO S/A

O valor lógico no segundo argumento da função, se FALSE, força a função a começar a pesquisa a partir do início do arquivo. Por isso a primeira chamada fica fora do WHILE.

É disso que você precisa?

[]'s
Maligno
http://www.buzinello.com/prg
Avatar de usuário

Maligno
Membro Master

Membro Master
 
Mensagens: 6390
Data de registro: 06 Jul 2004 01:40
Cidade/Estado: Londrina/PR
Curtiu: 1 vez
Mens.Curtidas: 14 vezes

Mensagempor Dri » 09 Out 2006 04:50

Well...

Maligno, este problema está num pequenino sistema que tenho (pequeno mesmo, três cadastros, uma transação de movimentos, e umas quatro consultas com opções de impressão).
Este sistema está compilado com a lib SIX2, utilizando índices NSX.
Adoro esta lib e utilizo alguns de seus recursos, inclusive a função sx_WildSeek().
Tirei uma noite no início da semana passada para deixar este sistema com Clipper puro, excluindo dele todas as libs externas, que por ser o menor que tenho, é ele que quero usar para fazer a primeira migração (estava convicta a ir para o xHarbour, lembra? E li qualquer coisa que o xHarbour não aceita a lib SIX na versão FREE, parece-me que só na versão paga).
A primeira coisa foi mudar o RDD para CDX, que foi tranqüilo.
Depois, foi substituir as funções da SIX2 por funções, comandos ou rotinas em Clipper.
Foi daí que pensei num índice temporário com o operador "$" para substituir a função sx_WildSeek() da SIX2.

Maligno, mil desculpas...
Quando citei
Há uma consulta onde um dos parâmetros é um campo que o usuário informará uma partícula do nome
deveria ter citado também que isto já é feito utilizando a função sx_WildSeek() da SIX2 e queria achar uma forma de substituí-la, mas não o fiz para encurtar o problema e acabei fazendo você perder um precioso tempo em me passar uma coisa que já faço. Não imaginei que você citaria esta função... Desculpe novamente... :( , mas muito obrigada!

Voltamos ao ponto de partida... :'(
Abraços!
Dri (F)
Dri
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 28
Data de registro: 06 Set 2004 20:09
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Mensagempor rochinha » 09 Out 2006 06:02

Amiguinha

Existe sim uma possibilidade de voce filtrar dados de forma super rapida e que podem substituir os indices temporários.

Use SETSCOPE() do CDX.

Primeiro voce cria um indice permanente, exemplo codigo de cliente, IDCLIENTE(supondo que seja de 5 digitos) para o arquivo de pedidos PEDIDOS.DBF

...
INDEX ON str(PEDIDOS->IDCLIENTE,5,0) ...
...

Depois em qualquer momento voce podera filtrar os dados deste cliente assim:

...
M->IDCLIENTE := PEDIDOS->IDCLIENTE
...
dbSelectArea("PEDIDOS")
OrdSetFocus(1) // sete o foco para o indice criado
SetScope(0, str(M->IDCLIENTE,5,0) ) // 0 define o inicio do Range
SetScope(1, str(M->IDCLIENTE,5,0) ) // 0 define o final do Range
dbGoTop()

Outro caso é voce filtrar varios registros em uma mesma tabela assim:

...
M->IDCLIENTE1 := 50
M->IDCLIENTE2 := 75
...
dbSelectArea("PEDIDOS")
SetScope(0, str(M->IDCLIENTE1,5,0) ) // 0 define o inicio do Range
SetScope(1, str(M->IDCLIENTE2,5,0) ) // 0 define o final do Range
dbGoTop()

Neste caso serao filtrados dados dos clientes com codigo 50 ate 75

Será que ajudou?

@braços :?)
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para fivolution@hotmail.com. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar de usuário

rochinha
Membro Master

Membro Master
 
Mensagens: 4538
Data de registro: 18 Ago 2003 20:43
Cidade/Estado: São Paulo - Brasil
Curtiu: 800 vezes
Mens.Curtidas: 242 vezes

Mensagempor Dri » 09 Out 2006 10:54

Hi, Rochinha!

Look this...
Primeiro, fiz o Maligno perder tempo fazendo-me citações a respeito da função sx_WildSeek() da SIX2, pois o sistema já era como ele sugeriu.
Agora, dê-me licença que deu pra mim e vou arrancar meus cabelos...
(Dois ou três minutos depois, semi-calva e mais calma...)

A SIX2 tem algo semelhante, acho que é sx_Setscope (não posso afirmar... não estou em casa e aqui onde estou não tem Clipper).
Como queria deixar o sistema sem libs de terceiros, em todos os lugares, principalmente nas funções que ativam o TBrowse, tirei todas as funções sx_Setscope e substituí por Whiles com controles de variáveis, etc., etc., etc...
Não imaginava que a lib DBFCDX.LIB tinha uma função similar... :'(
E a sx_WildSeek() (uma similar, claro!), a DBFCDX.LIB tem também?

A propósito, existe alguma documentação (NG, preferencialmente) para a DBFCDX.LIB? Ou fica no próprio NG do Clipper (como disse, não tem como eu ver aqui o NG do Clipper)?

Obrigada, gente! Apesar das asneiras que cometi neste tópico (e também no meu sistema "reinventando a roda" para substituir as funções da SIX2), a coisa tá fluindo bem, graças a estes amigos feras e sempre dispostos a ajudar!
Abraços!
Dri (F)
Dri
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 28
Data de registro: 06 Set 2004 20:09
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Mensagempor MARCELOG » 09 Out 2006 12:12

Olá Dri,
procure o NG do clipper 5.3 na internet, ele traz as informações das funções que controlam os índices cdx.
A função citada pelo Rochinha, s.m.j., é ORDSCOPE() e não SETSCOPE().
Importante destacar que o índice ativo tem que suportar a pesquisa.
Assim, quando criar um índice para filtro, fixo ou temporário, não esqueça essa situação.
Elabore índices compostos se necessário, pois permitirá diversas ordenações sem prejudicar a performance do filtro.
Lembre-se que os índices CDX comportam até 99 "ordens" de ordenação por arquivo (de índices).
Por outro lado, é importante que você leia tutoriais básicos, inclusive relativos aos rdd´s que você vai utilizar.
Sempre tem alguma coisa interessante que você pode usar para melhorar a performance ou reduzir codificação.
Contudo, se não precisar da informação, vai ter conhecimento de todas as funções e, tal qual o Rochinha fez, "lembrar" de alguma que atenda a sua necessidade e/ou possa ajudar os amigos.

MarceloG
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

Mensagempor MARCELOG » 09 Out 2006 12:24

Outra saída para o seu problema é jogar as informações em uma array e visualizar a mesma com tbrowse.
Em clipper, é importante que você tenha certeza absoluta de que o array a ser criado terá no máximo 4096 elementos.
No xHarbour este problema não existe.

Simples algorítimo:
..
Pega cvariavel para filtro

Ar:={}

use arquivo
DbGoTop()
Do While !Eof()
if cvariavel $ campodoarquivo
aadd(ar,{recno(),campo1,campo2,campo3,...})
endif
DbSkip() //ou DbSKip(1) para melhor legibilidade (Santo Perfeccionismo)
EndDo

Exibe array que admite qualquer ordenação, etc.

Inclui o nº do registro no exemplo para que, se o usuário escolher um item, você possa encaminhá-lo para o registro correspondente através da referência.

Na seção de download´s, tem exemplos para criar indice temporário e visualizar array, vê se ajuda.

Não deixe de ver, quanto a array´s, o www.caclipperwebsite.com

MarceloG
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

Mensagempor dbsh » 09 Out 2006 15:41

utilizo clipper 5.2e e blinker 7.0

oi se entendi voce esta querendo criar arquivo de indice temporario somente utilizando DBFCDX, utilizo da seguinte forma em um cliente com 25 maquinas em rede todos acessando o mesmo sistema e a mesma base de dados, utilizando indices temporarios em IDX sendo que os indices fixos do sistema e em CDX.
EX:
use arquivo inde aquivo new shar //extensão CDX
inde on campo to (TmpDBF := TmpDBF()) [for <expressão>] [while <exprtessão>]

TmpDbf() e uma funcao que gera arquivo temporario exclusivo com extensão IDX
Avatar de usuário

dbsh
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 115
Data de registro: 14 Jul 2004 14:19
Cidade/Estado: ES
Curtiu: 2 vezes
Mens.Curtidas: 15 vezes

Mensagempor Dri » 09 Out 2006 17:12

Hi, Marcelo e dbsh!

procure o NG do clipper 5.3 na internet, ele traz as informações das funções que controlam os índices cdx

Marcelo, jamais imaginava que no NG do Clipper 5.3 eu encontraria informações das funções que controlam os índices CDX... Agora, se é uma lib, tinha que ter documentação à parte, específica! Concorda?

A função citada pelo Rochinha, s.m.j., é ORDSCOPE() e não SETSCOPE().
Importante destacar que o índice ativo tem que suportar a pesquisa.
Assim, quando criar um índice para filtro, fixo ou temporário, não esqueça essa situação.

Mesma coisa da função similar da SIX2.

Lembre-se que os índices CDX comportam até 99 "ordens" de ordenação por arquivo (de índices).

Os índices NSX da SIX2 também suportam 99 "ordens" por arquivo de índice e, se não me engano, 15 arquivos de índices por cada arquivo DBF. Numa conta rápida: 1.485 ordens para cada arquivo DBF. Troço doido!!!

Por outro lado, é importante que você leia tutoriais básicos, inclusive relativos aos rdd´s que você vai utilizar.

Ai, minha orelha... rsrsrsrsrrs
Procurei alguma coisa sim, mas não encontrei. Não imagina que no NG do Clipper 5.3 eu encontraria. Até porque não uso e não gosto do Clipper 5.3 (acho que arrumei uma encrenca revelando isto...)

Em clipper, é importante que você tenha certeza absoluta de que o array a ser criado terá no máximo 4096 elementos.
No xHarbour este problema não existe.

No array eu já havia pensado, Marcelo, mas descartei exatamente pela limitação dos 4.096 elementos.
A lib FAST permite 16.777.216 elementos num array (4.096²). Só que é uma lib de terceiros, que estou evitando (por enquanto... logo, logo, enfio a SIX2, a FAST, a NANFOR... e pronto!!!).
O xHarbour eu já sabia que esta limitação não existe, entre outros recursos (32 bits, por exemplo), daí a minha idéia fixa de migrar para xHarbour, e até tenho um post a respeito... Mas terei que pensar bem, afinal, há controvérsias!!!
E não é só pelas controvérsias, afinal, migrar não é apenas recompilar, então não dá pra ter os sistemas rodando, a cada dia, com uma linguagem diferente! Quero dizer, se a decisão não for acertada, blau, blau! Terei uma linguagem que não me agrada e serei obrigada a engoli-la.

Na seção de download´s, tem exemplos para criar indice temporário e visualizar array, vê se ajuda

Estou vendo sim, Marcelo.
Mas estou achando este xHarbour meio complicado... Talvez até não seja, talvez seja devido minha familiaridade com o Clipper... Eu acho!

25 maquinas em rede todos acessando o mesmo sistema e a mesma base de dados, utilizando indices temporarios em IDX sendo que os indices fixos do sistema e em CDX


dbsh, interessante sua solução...
Se não me engano, ao criar um índice CDX sem TAG, sua extensão é IDX. É isto mesmo?
Ainda pretendo achar uma solução sem criar o índice temporário, porém, se não encontrar, sua sugestão para índice temporário pareceu-me a mais apropriada.

Brigada, people! Vocês estão realmente contribuindo com meus problemas, assim como contribuem com os problemas de todos mutuamente no grupo!
Abraços!
Dri (F)
Dri
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 28
Data de registro: 06 Set 2004 20:09
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Mensagempor Dri » 09 Out 2006 17:27

Hi!

Como disse, se realmente tiver que criar um índice temporário, aceitarei a sugestão do dbsh e, para nomear o arquivo idx criado, criarei um mecanismo que controlará o nome do arquivo.
Os arquivos ficariam assim: tmp00001.idx, tmp00002.idx, tmp00003.idx...
Os índices seriam criados localmente, e não na rede.

Raciocinando um pouco, acho que realmente não precisa bloquear ou abrir o arquivo em modo exclusivo para criar um índice, pois o que será reescrito será o índice, e não o DBF, e será um arquivo único de índice, ou seja, não há qualquer possibilidade de outro usuário estar com um arquivo aberto utilizando um índice que corre o risco de ser reescrito.

Concordam (mas só partirei pra índice temporário depois de esgotar outras possibilidades)?
Abraços!
Dri (F)
Dri
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 28
Data de registro: 06 Set 2004 20:09
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Mensagempor MARCELOG » 09 Out 2006 17:34

Perfeitamente justificável a sua dúvida,
investir tempo em algo que não se conhece bem é complicado.
É como trocar de namorado/a.
A namorada/o da gente não é "supra sumo" e tem várias vantagens, especialmente as limitações e defeitos que eu já connheço bem.
Mas, migrar para xharbour é fácil e quase indolor.
Com o uso do hbmake, mais fácil ainda.
Apenas a sua função principal vai mudar de nome, passando a se chamar main.
O resto, se você usa clipper puro, fica do mesmo jeito e funciona legal.

MarceloG

PS: se vai usar clipper mesmo, umas dicas:
1) Force a variável para o filtro com um número mínimo de caracteres (3,4,5,..., etc.).
Isso já reduz bem o número de elementos.

2) Crie um contador dentro do while e, se chegar a 4096 elementos, avise o usuário, peça para refinar a pesquisa e aborte o loop para evitar erro.
Não acredito que qualquer usuario vá percorrer e identificar 4096 itens.

3) Pegue o total de registros e divida por 4096.
Depois, com ajuda de um for/next, crie quantas array´s forem necessárias para cobrir o total de registros.
(Como essa variável vai ser private por causa de macro, acho que só podem existir 250, ou algo próximo, tenho que verificar)
Depois, preencha as arrays até achar o fim do arquivo.
Descarte as arrays vazias.
Exiba, com o tbrowse, a primeira array.
Se o usuário não achar o que procura nesta array, exiba a segunda, e assim sucessivamente.
Como o processamento será em nível de memória, vai ser bem rápido.
Com dbf temporário também não há problema, ou qualquer limitação.
Crie os campos do arquivo numa array, o nome exclusivo (único) do arquivo a ser criado e crie o mesmo.
Como vair ser único, abra exclusivamente o arquivo criado, procure no arquivo anterior os registros que atendem ao filtro e grave os mesmos no novo arquivo.
Crie os indices com o arquivo temporário exclusivo do jeito que quiser.
Abandonada a rotina, apague o arquivo temporário e índices criados.
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

Próximo



Retornar para Banco de Dados

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 8 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