Jump to content
Fivewin Brasil

SQLRDD X REDE


macs

Recommended Posts

Pessoal, bom dia!

Tenho uma tabela de registro único que guarda sequenciais de determinados campos, no caso o campo é "REQUISICAO"

Quando abro a tela de cadastro de requisições, verifico o conteúdo deste campo, somo + 1, e gravo este valor e apresento na tela esta numeração.

Mas em outra máquina na rede, quando o usuário está na mesma tela pra incluir outra requisição, não está trazendo o prox. código disponível. É como se estivesse visualizando ainda o sequencial anterior.

Como devo proceder?

A parte do código onde incremento o sequencial é essa:   

  ( cArqConf )->( SR_DbRefresh() )

      WHILE ! ( cArqConf )->( Rede_Registro() ) ; ENDDO

      IF ValType( ( cArqConf )->&cCampoAux. ) == "C"
         ( cArqConf )->&cCampoAux. := xNewSequencial
      ELSE
         ( cArqConf )->&cCampoAux. := Val( xNewSequencial )
      ENDIF

      ( cArqConf )->( DbCommit() )
      ( cArqConf )->( DbUnLock() )
      ( cArqConf )->( DbSkip(0)  )

 

Link to comment
Share on other sites

19 minutos atrás, Ariston Santos disse:

Algumas dúvidas:
• Em que momento você está salvando  xNewSequencial  incrementado + 1 ?
• Esta pode ser uma pergunta idiota mas, em &cCampoAux. , por que o . (ponto)?

Bloco de código Convertido pra melhor entendimento:

São Macros: Quando você quer uma garantia da conversão da Macro você utiliza o ".", hábitos da época do Clipper 

Está sendo dado o lock na tabela aqui. 
Fica em loop até que a tabela seja liberada, caso outro usuário esteja utilizando.
WHILE ! SEQ->( Rede_Registro() ) ; ENDDO   

IF ValType( SEQ->REQUISICAO ) == "C"
   SEQ->REQUISICAO := xNewSequencial       Está sendo salvo aqui
ELSE
   SEQ->REQUISICAO := Val( xNewSequencial )  ou Aqui
ENDIF

SEQ->( DbCommit() )
SEQ->( DbUnLock() )
SEQ->( DbSkip(0)  )
 
Link to comment
Share on other sites

18 minutos atrás, Ariston Santos disse:

Mais perguntas :)

• Não precisa de um DBAPPEND no dbf? É sempre apenas um registro, apenas incrementando SEQ->REQUISICAO+1?
• xNewSequencial já vem incrementado?
• SEQ->( DbSkip(0)  ) é realmente necessário?

O que postei é apenas a parte de atualização da tabela. xNewSequencial já vem incrementado.

DbSkip(0), para o SQLRDD, não sei se faz alguma diferença, mas pra DBF sim. Está aí porque a função é utilizada

pra meus programas tanto em DBF quanto SQL.

Link to comment
Share on other sites

18 minutos atrás, joao disse:

Boa tarde, 

 

Pode tentar :

Antes  :   Sr_BeginTransaction()

Depois :  SR_CommitTransaction()

Abei de fazer isso, mas não funciona. É como as informações que são gravadas em uma estação não fica visível para outra. A não ser que eu feche as tabelas e abra novamente.

Link to comment
Share on other sites

No meu ver o certo seria:

1-Busca o registro que vai atualizar ( dbseek() )

2-Trava o registro apenas e, não toda a tabela, por que para travar toda tabela precisa usar antes: SR_SetFastOpen(.F.) e depois SR_SetFastOpen(.T.)

3-Lê o campo atual, e da um REPLACE somando mais um

4-Faz o commit( DbCommit() ) e destrava o registro ( DbUnLock() )

Link to comment
Share on other sites

Em 28/05/2021 at 18:53, macs disse:

A rotina já tem o Sr_DbRefresh(), mas não funciona se eu não fechar e abrir a tabela!

Eu sugiro que faça a inclusão, sem fechar a tabela, em outra estação através de gerenciador ou rotina específica com select verifica se o valor foi incrementado. Caso sim banco está ok, do contrário pode ser alguma configuração de ambiente do bd. Pelo narrado tudo que teria que fazer na rotina para dar certo foi feito.

Para caso parecido com seu, eu usei uma segunda conexão, ao finalizar os dados eram fidelizados na tabela, no seu caso não me parece uma uma solução viável, uma vez simplesmente fechar a tabela resolve.

Se nada der certo, sugiro usar comando "update" ao invés do "replace".

Link to comment
Share on other sites

Em 29/05/2021 at 12:34, sygecom disse:

No meu ver o certo seria:

1-Busca o registro que vai atualizar ( dbseek() )

2-Trava o registro apenas e, não toda a tabela, por que para travar toda tabela precisa usar antes: SR_SetFastOpen(.F.) e depois SR_SetFastOpen(.T.)

3-Lê o campo atual, e da um REPLACE somando mais um

4-Faz o commit( DbCommit() ) e destrava o registro ( DbUnLock() )

É o que minha rotina já faz. 

Link to comment
Share on other sites

10 horas atrás, fluna disse:

Mas o sql tem um campo tipo incremento que já faz isso automaticamente pra você quando faz um append blank.... (último+1) -porque não usa? -já tentou?

Meu caso é diferente. Eu sei que existe o SR_RECNO da tabela que é auto incremento. Mas independente disso, eu gostaria de saber o motivo que tenho que fechar a tabela e abrir novamente pra ela vir com os valores dos campos atualizados! 

Como foi comentado aqui, pode ser alguma configuração do banco de dados.... mas qual? Tenho sistema com a SQLLIB do Vailton, utiliza a mesma função, e funciona normalmente, mas com o SQLRDD não funciona se eu não fechar a tabela.

Link to comment
Share on other sites

Mostre algo assim para critica, evite postar pedacos de programa.

/*
* SQLRDD Test
* Copyright (c) 2003 - Marcelo Lombardo
* All Rights Reserved
*/
	#include "sqlrdd.ch"
	#define RECORDS_IN_TEST                   1000
#define SQL_DBMS_NAME                       17
#define SQL_DBMS_VER                        18
	/*------------------------------------------------------------------------*/
	REQUEST DBFNTX
REQUEST DBFCDX
REQUEST DBFFPT
REQUEST DBFDBT
	FUNCTION Main( cRDD, cDSN )
	   LOCAL aStruct := { { "CODE_ID", "C", 8, 0 }, ;
      { "CARDID", "C", 1, 0 }, ;
      { "DESCR", "C", 50, 0 }, ;
      { "PERCENT", "N", 10, 2 }, ;
      { "DAYS", "N", 8, 0 }, ;
      { "DATE_LIM", "D", 8, 0 }, ;
      { "ENABLE", "L", 1, 0 }, ;
      { "OBS", "M", 10, 0 }, ;
      { "VALUE", "N", 18, 6 }, ;
      { "ID_EMPRESA", "C", 4, 0 } }
	   LOCAL nCnn, i
	   ? ""
   ? "Teste.exe"
   ? ""
   ? "Teste com SQLRDD "
   ? ""
	   ? "Connecting to database..."
	// SR_SetUseSequences(.T.)         // DESABILITA O CONTADOR DE SEQUENCIA AUTOMATICO
   SR_UseDeleteds( .F. )           // NÃO MANTER REGISTROS DELETADOS NAS TABELAS
   SR_SetFastOpen( .T. )             // ABRE AS TABELAS EM MODO COMPARTILHADO
   SR_SetGoTopOnScope( .F. )         // NÃO EXECUTA O DBGOTOP() AUTOMATICO NOS ORDSCOPE
   SR_MaxRowCache( 10 )            // Quantidade máxima de linhas mantidas em cache em tabelas do SQLRDD. O Default é 1000.
   SR_SetBaseLang( 2 )             // linguagem portugues
   SR_Msg( 2 )                       // portugues
   SR_SETSYNTHETICINDEX( .F. )       // vale o que for configurado pela função SR_SetSyntheticIndexMinimun().
   SR_SETSYNTHETICINDEXMINIMUN( 10 ) // Quantidade mínima de colunas na chave de índice para criá-lo como Sintético. Os valores aceitos são entre 0 e 10.
   SETPGSOLDBEHAVIOR( .T. )          // CONSIDERAR CAMPOS NULL COMO VAZIO
	   IF !Connect( "SQLRDD", "POSTGRES NATIVE" )
      Alert( 'Nao foi possivel conectar ao banco de dados...!' )
      CLOSE ALL
      QUIT
   ENDIF
	   ? "Connected to        :", SR_GetConnectionInfo(, SQL_DBMS_NAME ), SR_GetConnectionInfo(, SQL_DBMS_VER )
   ? "RDD in use          :", cRDD
   ? "Creating table      :", dbCreate( "TEST_TABLE", aStruct, "SQLRDD" )
	   USE "TEST_TABLE" EXCLUSIVE VIA "SQLRDD"
	   ? "Table opened. Alias :", Select(), Alias(), rddName()
   ? "Fieldpos( CODE_ID ) :", FieldPos( "CODE_ID" )
   ? "Fieldpos( DESCR )   :", FieldPos( "DESCR" )
	   ? "Creating 02 indexes..."
	   INDEX ON ID_EMPRESA + CODE_ID       TAG TEST_TABLE_IND01 TO TEST_TABLE
   INDEX ON Str( DAYS ) + DToS( DATE_LIM ) TAG TEST_TABLE_IND02 TO TEST_TABLE
	   ? "Appending " + AllTrim( Str( RECORDS_IN_TEST ) ) + " records.."
	   s := Seconds()
	   FOR i = 1 TO RECORDS_IN_TEST
      APPEND BLANK
      REPLACE ID_EMPRESA WITH '0001'
      REPLACE CODE_ID  WITH StrZero( i, 5 )
      REPLACE DESCR    WITH DToC( Date() ) + " - " + Time()
      REPLACE DAYS     WITH ( RECORDS_IN_TEST - i )
      REPLACE DATE_LIM WITH Date()
      REPLACE ENABLE   WITH .T.
      REPLACE OBS      WITH "This is a memo field. Seconds since midnight : " + AllTrim( Str( Seconds() ) )
	   NEXT
	   ? "dbClearIndex()      :", dbClearIndex()
   ? "dbCloseArea()       :", dbCloseArea()
	   USE "TEST_TABLE" SHARED VIA "SQLRDD"
	   ? "Opening Indexes"
   dbSetIndex( 'TEST_TABLE' )
	   ? "Set Order to 1      :", ordSetFocus( 1 )
   ? "Seek                :", dbSeek( "000100002" )
	   ? "found()             :", Found()
   ? "Recno(),bof(),eof() :", RecNo(), Bof(), Eof()
   ? "dbUnLock()          :", dbUnlock()
   ? "RLock(), dbRLockList:", RLock(), sr_showVector( dbRLockList() )
   ? "Writes to the WA    :", FIELD->DESCR := "Hello, SQL!", FIELD->PERCENT  := 23.55
   ? "dbCommit()          :", dbCommit()
   ? " "
	   ? "Press any key to browse()"
	   Inkey( 0 )
   CLEAR
	   ? "Order 1, key is     :", ordSetFocus( 1 ), ordKey()
	   ? "TOP Scope           :", ordScope( 0 )
   ? "BOTTOM Scope        :", ordScope( 1 )
	   ? "Press any key to browse() with another index and scope"
   Inkey( 0 )
   dbGoTop()
   CLEAR
   Browse( Row() + 1, 1, Row() + 20, 80 )
	   CLEAR
	   dbGoBottom()
   Alert( "Recno antes de deletar os registros: " + Str( RecNo() ) )
	   // ---------------- se comentar esse bloco aqui o problema desaparece -----------------
	   IF trava()
      DELETE
      UNLOCK
	      dbGoBottom()
	      DELETE
      dbUnlock()
	   ELSE
      Alert( "Nao foi possivel bloquear o Registro...!" )
   ENDIF
	   // -------------------------------------------------------------------------------------
	   dbGoBottom()
   Alert( "Recno depois de deletar os 2 registros: " + Str( RecNo() ) )
	
   ? "Order 1, key is     :", ordSetFocus( 1 ), ordKey()
	   // ---------------- ou se não utilizar scope também não acontece o erro  ----------------------
	   SET SCOPE TO '0001', '9999'
	   ? "TOP Scope           :", ordScope( 0 )
   ? "BOTTOM Scope        :", ordScope( 1 )
	   ? "Press any key to browse() with another index and scope"
   Inkey( 0 )
   dbGoTop()
   CLEAR
   Browse( Row() + 1, 1, Row() + 20, 80 )
	   SET SCOPE TO            // Desativa ESCOPO
	   dbGoBottom()
   IF trava()
      Alert( 'vou apagar o registro: ' + Str( RecNo() ) )
      DELETE
      dbUnlock()
   ENDIF
	   dbGoBottom()
	   Alert( "Recno depois de deletar 3º registro: " + Str( RecNo() ) )
	   ? "Pressione qualquer tecla para incluir um novo registro registro()"
   Inkey( 0 )
	   IF inclui()
      REPLACE ID_EMPRESA WITH '0001'
      poecodigo( { 'ID_EMPRESA', 'CODE_ID' }, 5 )
      REPLACE DESCR    WITH DToC( Date() ) + " - " + Time()
      REPLACE DAYS     WITH ( RECORDS_IN_TEST - i )
      REPLACE DATE_LIM WITH Date()
      REPLACE ENABLE   WITH .T.
      REPLACE OBS      WITH "This is a memo field. Seconds since midnight : " + AllTrim( Str( Seconds() ) )
      dbCommit()
   ENDIF
	   RETURN NIL
	// *************
FUNC trava
	// *************
	   PRIVATE tt
   FOR tt = 1 TO 10
      IF RLock()
         EXIT
      ENDIF
      Inkey( 0.1 )
   NEXT tt
   IF !RLock()
// alert('Registro do arquivo: ' + dbf() + ';Bloqueado em outro terminal.. !')
      Alert( 'Registro ' + if( UsaSgbd, 'da Tabela: ', 'do Arquivo: ' ) + Alias() + ';Esta Sendo Utilizado Em Outro Terminal,;' + ;
         'Libere o Registro para continuar...' )
	   ENDIF
	   RETURN RLock()
	// **************
FUNC inclui
	// **************
	   PRIVATE ordem, tt
   ordem = IndexOrd()
   FOR tt = 1 TO 10
      APPEND BLANK
      Alert( 'Recno no append blank: ' + Str( RecNo() ) )
      IF !NetErr()
         EXIT
      ENDIF
      Inkey( 0.1 )
   NEXT tt
	   IF NetErr()
      Alert( if( UsaSgbd, 'Tabela ', ' Arquivo ' )  + ' Bloqueado por Outro Usuario - NÆo e poss¡vel incluir registros !' )
   ENDIF
	   RETURN !NetErr()
	// ******************
PROCEDURE PoeCodigo
	// ******************
   LOCAL cCampoTemp
   PRIVATE cCampoAux
	   PARA campo, tama, OrdemPara, MemoriaPara
	   OrdemPara   = if( PCount() > 2, OrdemPara, 1 )
   MemoriaPara = if( PCount() > 3, MemoriaPara, .T. )
	   cCampoAux = ''
	   IF Type( 'campo' ) = 'A'      // Aqui testa para verificar se tem mais de um campo a chave
      FOR xyz = 1 TO Len( campo ) - 1
         cCampoTemp = campo[ xyz ]
         cCampoAux += &cCampoTemp.
      NEXT xyz
      campo = campo[ Len( campo ) ]
   ENDIF
	   m->registro = RecNo()
   m->ordem    = IndexOrd()
   m->tama     = tama
   SET ORDER TO ordempara
   Alert( 'Recno do inclui: ' + Str( RecNo() ) )
   DO WHILE .T.
      dbGoBottom()
      ProvAux = StrZero( Val( &campo ) + 1, m->tama )
      SEEK cCampoaux + ProvAux
      IF Found()
         IF Empty( &campo. )                      // Coloquei esse bloco de codigo para evitar o loop
            IF trava()  // rlock()                          && enterno quando o valor do registro era em branco.
               REPLACE &campo. WITH ProvAux
            ENDIF
         ENDIF
         LOOP
      ELSE
         IF CodigoUnico()
            EXIT
         ENDIF
      ENDIF
   ENDDO
	   dbGoto( m->registro )
	   SET ORDER TO m->ordem
	   RETURN
	// *******************
FUNCTION codigounico
	// *******************
	   dbGoto( m->registro )
	   IF trava() // rlock()
      REPLACE &campo. WITH ProvAux
   ENDIF
	   dbCommit()
	   SEEK cCampoAux + ProvAux
// alert('Registro: ' + str(m->Registro) +';Recno: ' + str(recno()) )
	   IF Found() .AND. m->registro = RecNo()
      RETURN .T.
   ENDIF
	   RETURN .F.
	/*------------------------------------------------------------------------*/
	#include "connect.prg"
/*------------------------------------------------------------------------*/

Regards, saludos.

Link to comment
Share on other sites

** Função....: GetSequencial()                                                         *
** Objetivo..: Retorna o proximo codigo sequencial dos campos informados               *
** Autor.....: Márcio Augusto Cezar                                                    *
** Data......: 08/03/2020                                                              *
****************************************************************************************
** Parâmetros: cAliasSeq  --> Alias da tabela que guarda o sequencial do campo         *
**             cFieldSeq  --> Campo a ser localizado na tabela que guarda o sequencial *
**             cAliasPesq --> Alias da Tabela onde será pesquisada a existência do     *
**                            sequencial retornado                                     *
**             cFieldPesq --> Nome do campo da tabela a ser pesquisada a existência    *
**             nTamField  --> Tamanho do campo                                         *
**             nTamZeros  --> Total de Zeros a Esquerda                                *
**             cKey       --> Informação que fará parte da pesquisa                    *
**             cFieldKey  --> Campo que receberá o valor da chave                      *
****************************************************************************************
** Retorno...: NIL                                                                     *
****************************************************************************************
** Observação: O arquivo que guarda o código sequencial (cAliasSeq), tem que está posi-*
**             cionado no registro correto.                                            *
****************************************************************************************
#Include "ERPConfig.Ch"

FUNCTION GetSequencial( cAliasSeq, cFieldSeq, cAliasPesq, cFieldPesq, nTamField, nTamZeros, cKey, lAtualiza, cIndex )

   LOCAL nPosReg := 0
   LOCAL bCondicao
   LOCAL xNewSequencial := ""
   LOCAL cSetIndex
   LOCAL nSelect := Select()

   #IfDef SQL_RDD

      ( cAliasSeq )->( DbCloseArea() )
     //( cAliasPesq )->( DbCloseArea() )

      && -- Checando se existe empresas cadastradas
      oOpenTable := TOpenTable():New()

      && -- Abrindo tabela de dados em modo exclusivo
      IF ! oOpenTable:openTablesAlias( { cAliasSeq } )

          oOpenTable:End()

          RETURN .F.

      ENDIF

      SR_BeginTransaction()
      
   #Endif

   DEFAULT cKey      := ""
   DEFAULT lAtualiza := .F.
   DEFAULT nTamField := len( &cAliasPesq.->&cFieldPesq. )
   DEFAULT nTamZeros := len( &cAliasPesq.->&cFieldPesq. )

   IF cIndex <> NIL
      cSetIndex := ( cAliasPesq )->( SetIndex( cIndex ) )
   ENDIF

   cCampoAux  := cFieldSeq
   cCampoAux2 := cFieldPesq
   cArquivo   := cAliasPesq
   cArqConf   := cAliasSeq

   #IfDef SQL_RDD
     ( cArqConf )->( Sr_DbRefresh() )
     ( cArquivo )->( Sr_DbRefresh() )
   #Endif

   IF empty( ( cArqConf )->&cCampoAux. )

      IF ! empty( ( cArqConf )->&cCampoAux. ) .AND. empty( nTamField )
         nTamField := len( alltrim( ( cAliasPesq )->&cFieldPesq. ) )
      ENDIF

      ( cArquivo )->( dbGoBottom() )

      IF ( cArqConf )->( lastRec() ) == 0
         bCondicao := { || ( cArqConf )->( Rede_Append()  ) }
      ELSE
         bCondicao := { || ( cArqConf )->( Rede_Registro() ) }
      ENDIF

      WHILE ! EVal( bCondicao ) ; ENDDO

      IF ValType( ( cArqConf )->&cCampoAux. ) == "C"
         IF ValType( ( cArquivo )->&cCampoAux2. ) == "C"
            ( cArqConf )->&cCampoAux := strZero( Val( ( cArquivo )->&cCampoAux2. ), nTamField )
         ELSE
            ( cArqConf )->&cCampoAux := strZero( ( cArquivo )->&cCampoAux2., nTamField )
         ENDIF
      ELSE
         IF ValType( ( cArquivo )->&cCampoAux2. ) == "C"
            ( cArqConf )->&cCampoAux := Val( ( cArquivo )->&cCampoAux2. )
         ELSE
            ( cArqConf )->&cCampoAux := ( cArquivo )->&cCampoAux2.
         ENDIF
      ENDIF

      ( cArqConf )->( dbCommit() )
      ( cArqConf )->( dbUnLock() )
      ( cArqConf )->( dbSkip(0)  )

      xNewSequencial := ( cArqConf )->&cCampoAux.

      IF ValType( ( cArqConf )->&cCampoAux. ) == "C"
         xNewSequencial := strZero( val( ( cArqConf )->&cCampoAux. ) + 1, nTamField )
      ELSE
         xNewSequencial := strZero( ( cArqConf )->&cCampoAux. + 1, nTamField )
      ENDIF

      IF cSetIndex <> NIL
         ( cAliasPesq )->( SetIndex( cSetIndex ) )
      ENDIF

      RETURN xNewSequencial

   ENDIF

   nPosReg := ( cArquivo )->( RecNo() )
   bSeek   := < ||

                IF ValType( ( cArquivo )->&cCampoAux2. ) == "C"
                   IF ValType( ( cArqConf )->&cCampoAux. ) == "C"
                      ( cArquivo )->( DbSeek( cKey + pad( strZero( val( ( cArqConf )->&cCampoAux. ) + 1, nTamZeros ), nTamField ) ) )
                   ELSE
                      ( cArquivo )->( DbSeek( cKey + pad( strZero( ( cArqConf )->&cCampoAux. + 1, nTamZeros ), nTamField ) ) )
                   ENDIF
                ELSE
                   IF ValType( ( cArqConf )->&cCampoAux. ) == "C"
                      ( cArquivo )->( DbSeek( cKey + pad( Str( val( ( cArqConf )->&cCampoAux. ) + 1, nTamZeros ), nTamField ) ) )
                   ELSE
                      ( cArquivo )->( DbSeek( cKey + pad( Str( ( cArqConf )->&cCampoAux. + 1, nTamZeros ), nTamField ) ) )
                   ENDIF
               ENDIF

               RETURN ( cArquivo )->( Found() )

              >

   IF EVal( bSeek )

      SysRefresh()

      WHILE .T.

         IF ! EVal( bSeek )
            EXIT
         ENDIF

         WHILE ! ( cArqConf )->( Rede_Registro() ) ; ENDDO

         IF ValType( ( cArqConf )->&cCampoAux. ) == "C"
            ( cArqConf )->&cCampoAux. := strZero( val( ( cArqConf )->&cCampoAux. ) + 1, nTamZeros )
         ELSE
            ( cArqConf )->&cCampoAux. += 1
         ENDIF

         ( cArqConf )->( dbCommit() )
         ( cArqConf )->( dbUnLock() )
         ( cArqConf )->( dbSkip(0)  )
         
         Sleep(.1)

      ENDDO

   ENDIF

   ( cArquivo )->( dbGoTo( nPosReg ) )

   IF ValType( ( cArqConf )->&cCampoAux. ) == "C"
      xNewSequencial := strZero( Val( ( cArqConf )->&cCampoAux. ) + 1, nTamZeros )
   ELSE
      xNewSequencial := strZero( ( cArqConf )->&cCampoAux. + 1, nTamZeros )
   ENDIF

   IF lAtualiza

      WHILE ! ( cArqConf )->( Rede_Registro() ) ; ENDDO

      IF ValType( ( cArqConf )->&cCampoAux. ) == "C"
         ( cArqConf )->&cCampoAux. := xNewSequencial
      ELSE
         ( cArqConf )->&cCampoAux. := Val( xNewSequencial )
      ENDIF

      ( cArqConf )->( DbCommit() )
      ( cArqConf )->( DbUnLock() )
      ( cArqConf )->( DbSkip(0)  )

   ENDIF

   #IfDef SQL_RDD

      SR_CommitTransaction()
      SR_EndTransaction()
      
      DbSelectArea( nSelect )
      
   #Endif

   IF cSetIndex <> NIL
      ( cAliasPesq )->( SetIndex( cSetIndex ) )
   ENDIF

RETURN pad( xNewSequencial, nTamField )

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...