Clipper On Line • Ver Tópico - ADO / SQLMIX / ADOXB

ADO / SQLMIX / ADOXB

Discussão sobre SQL

Moderador: Moderadores

 

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 13:14

A intenção não é criar polêmica, é apenas criar um roteiro pra facilitar o uso.
Nas mensagens existentes, está tudo incompleto, ou poluído, o que não ajuda em nada.

Vou escrever a parte do ADO, que é o que uso.
As outras opções, fica a cargo de quem usa, se quiser colocar.

Pra clarear melhor o que precisa, dividir em:

1. Visão geral do banco de dados cliente/servidor (comum a todas)
2. O que precisa
3 - Conectar ao banco de dados
4 - Ler informações
5 - Incluir/alterar/excluir
6 - Mais informações
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 13:24

1 Visão geral

Em cliente/servidor, o programa não acessa diretamente o banco de dados pra nada.
Tudo que o programa quiser, tem que pedir pro servidor.
A única ligação com o servidor é uma simples conexão.

Não é uma base DBF, então podem existir tipos de campos que não existem no DBF.
É comum existir campo nulo/vazio, seja qual for o tipo de campo.
Se o campo for numérico, e estiver vazio, se comparar com zero vai dar erro.
Vazio é diferente de zerado, ou diferente de string tamanho zero.

Também tem o detalhe de datas.
O MySql, dependendo da versão/configuração, aceita data com conteúdo "00/00/00".
O mais comum é não aceitar data zerada, e teria que usar o conteúdo vazio. (NULL)

Nas bases cliente/servidor, ao contrário dos DBFs, há muito mais opções.
Pode ser usado por exemplo, um default para valores sendo zero, assim já se garante que não vai ter campo numérico com conteúdo vazio.

Também tem opção de criar validações, rotinas pré-definidas, relacionamento entre tabelas, etc.

Isso é outro diferencial:
No servidor, existirão os bancos de dados, que apenas pra efeito de entender, é como se fossem as pastas.
As tabelas, serão como se fossem os DBFs, e ficam dentro dos bancos de dados.

Então poderia usar uma conexão pra trabalhar com vários bancos de dados diferentes, por exemplo um pra cada empresa.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 13:30

2 - O que precisa (ADO)

Servidor
Se é cilente/servidor, precisa de um servidor.
No caso do MySql, instalar o servidor MySql no servidor.

Terminal
A conexão é feita geralmente pelo ODBC.
Cada base de dados tem seu próprio ODBC.
Se for MySql, o ODBC MySql, baixado no site do MySql
É instalar no Windows.

Programa
Nada.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 13:44

3 -Conectar com o banco de dados (ADO)

Se tudo é feito por uma conexão, precisa da conexão.
Ela contém informações sobre aonde está o servidor, qual a porta a ser usada, qual o ODBC de banco de dados a ser usado, usuário, senha, e outras informações que podem ser necessárias.

A opção que passei a usar foi uma única conexão para o aplicativo inteiro.
Abro no início do aplicativo, e fecho no final.
Isto eliminou alguns problemas que estavam ocorrendo, quando estava usando abrir/fechar toda hora.
Pode usar uma varíavel pública para o sistema inteiro.
Atualmente com multithread, uso uma função estática, e uma variável dentro dela.
Mas pode usar uma em cada módulo, ou a cada consulta, vai de cada um, ou do que encontrar pela frente.

// Início do aplicativo:
Conexao():Open()

// final do aplicativo:
Conexao():Close()

// Função auxiliar
FUNCTION Conexao()
    STATIC oConexao
   IF oConexao == NIL
      oConexao := win_OleCreateObject( "ADODB.Connection" )
      oConexao:ConnectionString := "Driver=" + cMySqlDriver + ";Server=" + cServer + ";Option=131072;Stmt=;" + ;
         "Database=" + cDatabase + ";User ID=" + cUser + ";Password=" + cPassword + ";"
      oConexao:CursorLocation    := adUseClient // cliente
      oConexao:CommandTimeOut    := 60 // seconds
      oConexao:ConnectionTimeOut := 60 // seconds
   ENDIF
   RETURN oConexao


A diferença é que deste jeito acesso de qualquer módulo, mesmo em multithread.
Vai ser sempre uma única conexão, não importa quantos módulos estejam abertos.

Como dá pra perceber, toda informação de banco de dados, localização do servidor, usuário, senha, e parâmetros extras estão na string de conexão.
Essa é uma opção pra MySql, poderia ser pra qualquer outra base de dados
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 13:59

4 - Ler informações (ADO)

É aqui que vai determinar o desempenho de tudo.
Quanto melhor detalhar ao servidor o que quer, melhor vai ter o resultado pronto.
Pode pedir um simples nome de cliente, ou vendas totalizadas por data, ou vendas totalizadas por cliente, ou informações que envolvem diversas tabelas, na ordem que quiser e do jeito que quiser.

Se for fazer um relatório de vendas totalizado por data, melhor já pedir pronto pro servidor.
Se ficar pedindo um lançamento por vez, vai ficar até mais demorado que dbf.
Se pedir campos que não precisa, vai estar só fazendo demorar mais.

Então esta será a opção mais usada de todas.
No caso do ADO, é retornado em formato ADO.
Lembrando que a conexão já foi aberta no início. Para o módulo seria só esta parte mesmo.

oResultado := Conexao():Execute( "SELECT CODIGO, NOME FROM CLIENTES ORDER BY NOME" )
DO WHILE .NOT. oResultado:Eof()
   ? oResultado:Fields( "CODIGO" ):Value
   ? oResultado:Fields( "NOME" ):Value
   oResultado:MoveNext()
ENDDO
oResultado:Close()


oResultado é o resultado. É algo como um arquivo temporário, mas no formato ADO
Após usar o resultado, precisa fechar esse "temporário", é o que faz no final o oResultado:Close()

oResultado:Fields( "CODIGO" ):Value
Isso é o campo, seria algo parecido com o FieldGet() do Cipper/Harbour, com a diferença que aceita número ou nome.
E :Value porque o que interessa é o valor. Também dá pra ver outras coisas do campo, mas não interessam no resultado.

oResultado:MoveNext()
É o equivalente do SKIP. É que estamos usando o ADO, e nele chama-se MoveNext()
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 14:07

5 - Incluir, alterar, excluir (ADO)

O restante é tudo igual, porque trata-se de executar comandos SQL.
Também vale pra criar tabelas, apagar tabelas, criar índices, etc, porque é tudo por comando SQL.
Lembrando que a conexão já foi aberta no início, no fonte do módulo é só isto mesmo.

// incluir
oConexao():Execute( "INSERT INTO CLIENTES ( CODIGO, NOME ) VALUES ( 1, 'ANTONIO' )

// alterar
oConexao():Execute( "UPDATE CLIENTES SET NOME='OUTRO' WHERE CODIGO=1" )

// excluir
oConexao():Execute( "DELETE FROM CLIENTES WHERE CODIGO=1" )

//criar tabela
oConexao():Execute( "CREATE TABLE CLIENTES (  CODIGO INT 11 DEFAULT 0, NOME CHAR(30) ):  )

José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 14:32

6 - Considerações finais (ADO)

É isso.
Se sabe abrir o banco, ler informações, gravar, excluir, incluir, criar tabela, já sabe tudo.

Mas e os comandos SQL? E os tipos caractere,numérico? E os índices? E os recursos adicionais?

Isso vai ter que ir atrás, porque estamos falando de qualquer base de dados.
Tem base de dados que pode obrigar a existir o índice principal com campo único, tem base de dados que pode ter um tipo de campo que não existe na outra base de dados, tem base de dados com muuuitos recursos, etc. etc. etc.

Até um tempo atrás existia uma pequena diferença entre comandos SQL da Microsoft e do MySql, não sei se ainda existe.
A opção de lmitar o resultado da pesquisa a um único registro

// SQL Server
SELECT TOP 1 CODIGO FROM CLIENTES ORDER BY CODIGO DESC

// MySql
SELECT CODIGO FROM CLIENTES ORDER BY CODIGO DESC LIMIT 1


Os comandos SQL são padrão, então se existir diferença, vão ser mínimas.
A partir daqui, é aprender a base de dados que vai usar, qual string de conexão que ela precisa, se tem algum detalhe diferente nos comandos SQL, e quais os recursos adicionais que ela oferece.

Como deu pra perceber, vai ser muita mudança nos fontes, em tudo que mexe com base de dados.

Quem está acostumado com DBF, em abrir vários arquivos, selecionar área, selecionar índice, pesquisar em vários arquivos pra tirar um relatório, etc. acaba se confundindo por não precisar mais nada disso,

Como pode uma única conexãozinha substituir milhares de arquivos dbfs abertos?
Será que isso funciona mesmo?
Esse monte de comando não vai deixar tudo lento?
Como o servidor sabe quem tá pedindo o que?

Acreditem. Funciona e muito bem.

Só imaginar que na internet, quando você contrata um banco de dados no site, você é um dos milhares de usuários daquelele mesmo servidor.
Milhares de usuários, de milhares de empresas, todos acessando o mesmo servidor, mas cada um trabalhando com o seu banco de dados, com muitos usuários.
Se esse uso é normal e funciona, usar numa única empresa é brincadeira de criança pro servidor.

Agora só de comparação, tente imaginar milhares de usuários, de milhares de empresas, usando os DBFs de um mesmo servidor.
Dá pra comparar?

Faltou dizer....
E como vemos os arquivos no no servidor?
Acreditem ou não, pode ser tudo um único arquivo, mas vai olhar pra que?

E backup?
Tem ferramenta pra isso.

E se der problema?
Ué... pra isso sempre existiu backup.

Que tipo de problema pode acontecer?
Igual uma máquina comum, é bom ter nobreak, se for por internet a internet pode cair, se for pela rede a rede tem que estar funcionando.
Mas arquivo corrompido, índice estragado, aparentemente impossível.
É o servidor que mexe nos arquivos. Se acabar a luz, tudo que foi enviado ao servidor foi feito por ele, nenhum terminal mexe no servidor, então acabar a luz não faz diferença pro servidor, a não ser que não tenha nobreak.

E os arquivos abertos pelo terminal antes de acabar a luz?
Arquivos abertos? Isso não existe.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor janio » 27 Fev 2015 15:54

Parece muito bom, Quintas!
:{

Janio
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1709
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 7 vezes
Mens.Curtidas: 39 vezes

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 16:00

Obrigado.

Esqueci uma coisa importante:
Como dá pra perceber, não existe registro atual.
Na hora do UPDATE, que seria o REPLACE, é obrigatório identificar exatamente qual o registro que vai ser alterado.
Se esquecer disso, seria igual REPLACE ALL, vai trocar tudo de uma vez.
O mesmo vale pro DELETE.

E só lembrando: tudo isso não é vantagem do ADO, e sim do uso de cliente/servidor.
ADO é apenas uma das formas de se usar/codificar.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor sygecom » 27 Fev 2015 18:45

Muito bom, e muito bem explicado, parabéns.
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
leonardodemachado@hotmail.com
Avatar de usuário

sygecom
Membro Master

Membro Master
 
Mensagens: 6551
Data de registro: 21 Jul 2006 10:12
Cidade/Estado: Alvorada-RS
Curtiu: 1 vez
Mens.Curtidas: 57 vezes

ADO / SQLMIX / ADOXB

Mensagempor janio » 27 Fev 2015 19:20

Ola,

Nao precisar estar ABRINDO e FECHANDO as tabelas?

A cada SELECT * FROM a tabela eh re-aberta?

Pergunto pq no dbf, como se sabe, abrimos a tabela e ela fica la aberta... a cada vez q precisamos de algum dado daquela tabela apenas damos um Select Tabela e pegamos os dados do ponteiro atual ou movemos o ponteiro com dbgotop(), dbseek()... conforme a necessidade.

Janio
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1709
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 7 vezes
Mens.Curtidas: 39 vezes

ADO / SQLMIX / ADOXB

Mensagempor JoséQuintas » 27 Fev 2015 21:02

O terminal não mexe nos arquivos.
O terminal apenas pede pro servidor e o servidor responde.
Portanto, nada de arquivo aberto no terminal.
Muito menos algum compartilhamento no servidor.

E o servidor com o banco de dados pode ser Linux ou Windows.
E o terminal rodando o programa pode ser Linux ou Windows.

O único canal de comunicação entre a base de dados e o terminal é o servidor, pela conexão e nada mais.

Como forma didática, compare com o messenger/skype/whatsup.
O terminal envia a mensagem pro servidor, e o servidor responde.
Pede a lista dos clientes em ordem alfabética, e o servidor devolve a lista.
Nenhum acesso direto à base de dados.
Se acabar a luz, só a mensagem em andamento pode ser perdida, e não estraga em nada todo resto, porque não faz parte do banco de dados, é apenas uma mensagem.

Por falar nisso.... esse exemplo serve pra demonstrar como ganhar velocidade.
Imagine isso mesmo, como messenger/skype/whatsup.
Num relatório, se pedir um cliente por vez, seriam milhares de mensagens.
Se pedir o relatório inteiro, seria uma mensagem só.
Quanto melhor aproveitar as mensagens, melhor o resultado.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 10018
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 6 vezes
Mens.Curtidas: 641 vezes

ADO / SQLMIX / ADOXB

Mensagempor alxsts » 01 Mar 2015 01:54

Olá!

Parabéns Quintas!

Belo trabalho, bacana mesmo. Considero um embrião que pode crescer muito.

Não conheço nada de SQLMix nem de ADOXB. Gosto bastante de ADO, pois trabalhei com ele junto com VB6 (pena que só funcione em Windows). Gostei da implementação ADO na HbWin, que permite trabalhar no formato OOP usando as classes ADO. É uma tecnologia antiga, já superada pela ADO dot Net mas ainda muito usada e com muitos conhecedores do assunto.

Espero que o tópico cresça, com o aporte de exemplos das três tecnologias. Se eu conseguir, coloco algo sobre ADO. Faz tempo que quero fazer isto mas não tenho tido tempo.

Uma pergunta que não quer calar: no SQL Mix, como fazer para executar uma stored procedure, passando alguns parâmetros de entrada e recebendo como retorno um record set ou um valor?
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2152
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 13 vezes
Mens.Curtidas: 142 vezes

ADO / SQLMIX / ADOXB

Mensagempor Poka » 01 Mar 2015 08:51

Olá José Quintas, obrigado pelos relatos das suas experiências. Muito útil mesmo. Existiam várias coisas que eu queria saber sobre banco cliente/servidor, e você explicou realmente o que eu queria saber:
-não precisar parar todos para indexar ( como dizem , talvez nem precise de índice) , depende do tamanho da tabela? , afinal qual o tamanho da tabela para precisar de índice?
No meu ponto de vista 50.000 , 100.000 registros por exemplo é uma tabela pequena, 500.000 registros precisaria de índice?
- não existir + arquivos abertos no terminal ( cansa ver Aliás não existe).
- não ter + problemas com queda de energia no terminal , mas principalmente quando o usuário desliga o terminal “daquele jeitão”.
Não ter que parar pra criar campo novo, com dbfs tenho na rotina de indexação, antes de indexar, salvo o arquivo no com nome temporário, crio arquivo vazio, e dou appe from, depois elimino o arquivo temporário, mas caso trave ou pare a energia no meio da indexação, é um problema. Me parece que com banco cliente servidor nã vou precisar de nada disso, estava fazendo uns testes aqui, vou fazer o seguinte, a tabela sempre crio com o primeiro campo, o campo chave por exemplo, depois somente altero os outros campos, parece que se vc alterar algum campo para tamanho menor ele não altera, isso por segurança de perda de dados, se o campo for maior ele altera, se não existir ele cria, isso sem ter que sair todo mundo do sistema. Nada de appe from , criar temporários, deleta temporários, etc , abrir e fechar arquivos em cada módulo, entrar em outro módulo, abrir quase os mesmos arquivos, fechar novamente, não é fácil , não precisar + disso parece mesmo ser uma maravilha. Sem contar que podemos fazer no próprio banco de dados o que usuário pode ou pode fazer.
- estou iniciando aqui há alguns meses aqui com Firebird + ODBC, estou gostando bastante. Criei umas funções aqui para criar tabelas e principalmente incluir registros onde eu envio uma matriz para a função, assim como fazemos normalmente com o dbf, e não ficar CREATE TABLE CAMPO1 TIPO X, CAMPO2, CAMPO3 . imagina fazer isso com 50 campos numa tabela, o mesmo com insert. Assim que tiver pronto alguma coisa aqui vou postar aqui no fórum para compartilhar e também pedir ajuda para os colegas para melhorar.
Comprei um livro aqui, peguei bastante funções da internet e estou montando as funções para usar no sistema. Minha intenção e criar as funções para fazer o serviço pesado com os comandos SQL e esquecer que existe esses comandos, como se estivesse numa dll por exemplo.
Vou colocar uma base de dados grande aqui e testar o Select para ver se é rápido mesmo, ou se vai ser o SET FILTER da vida.
Em tempo,
Fiz um teste simples aqui, abri um dbf somente com um campo e inclui 100.000 registros, fiz o mesmo com Firebird + ODBC para testar a velocidade.
Com Firebird 3 (tres) minutos
Com DBF 3 (três) SEGUNDOS???????????.

Poka.
Avatar de usuário

Poka
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 365
Data de registro: 25 Out 2004 21:26
Cidade/Estado: Leme/SP
Curtiu: 0 vez
Mens.Curtidas: 15 vezes

ADO / SQLMIX / ADOXB

Mensagempor alxsts » 01 Mar 2015 23:24

Olá!

Poka escreveu:No meu ponto de vista 50.000 , 100.000 registros por exemplo é uma tabela pequena, 500.000 registros precisaria de índice?

Duas regras básicas para agilizar o processamento de consultas:

1 - toda tabela deve ter uma chave primária, que automaticamente cria um índice.
2 - deve haver índice para todos os campos referenciados nas cláusulas WHERE de suas consultas, se eles não forem a chave primária.

Quanto ao comparativo de tempos do teu teste, isto é normal. O DBF sempre será mais rápido pois ele apenas inclui os registros na tabela e índices, se houver, enquanto um gerenciador de banco de dados relacional executa muitos outros controles ao inserir cada registro.
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2152
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 13 vezes
Mens.Curtidas: 142 vezes

Próximo



Retornar para SQL

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 1 visitante


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