Clipper On Line • Ver Tópico - Facilitar criação de tabela no fonte
Página 1 de 2

Facilitar criação de tabela no fonte

MensagemEnviado: 11 Set 2016 22:26
por JoséQuintas
Tá tudo bem, funcionando direito, mas queria deixar isto mais reduzido.

STATIC FUNCTION JPPREHISCreateMySql()

   RETURN ;
   "CREATE TABLE IF NOT EXISTS JPPREHIS ( " + ;
   "PHID     INT(11)      NOT NULL AUTO_INCREMENT, " + ;
   "PHITEM   VARCHAR(6)   NOT NULL DEFAULT '', " + ;
   "PHCADAS  VARCHAR(6)   NOT NULL DEFAULT '', " + ;
   "PHFORPAG VARCHAR(6)   NOT NULL DEFALT '', " + ;
   "PHDATA   DATE         NULL, " + ;
   "PHHORA   VARCHAR(8)   NOT NULL DEFAULT '', " + ;
   "PHVALOR  DOUBLE(16,4) NOT NULL DEFAULT '0', " + ;
   "PHOBS    VARCHAR(60)  NOT NULL DEFAULT '', " + ;
   "PHINFINC VARCHAR(80)  NOT NULL DEFAULT '', " + ;
   "PHINFALT VARCHAR(80)  NOT NULL DEFAULT '', " + ;
   "PRIMARY KEY    ( PHID ), " + ;
   "INDEX IDXITEM  ( PHITEM, PHCADAS, PHFORPAG, PHDATA DESC, PHHORA DESC ), " + ;
   "INDEX IDXCADAS ( PHCADAS, PHITEM, PHFORPAG, PHDATA ), " + ;
   "INDEX IDXDATA  ( PHDATA, PHITEM, PHCADAS, PHFORPAG ) " + ;
   ") COLLATE=latin1_swedish_ci ENGINE=InnoDB"


Parece que qualquer tentativa de reduzir isso acaba causando um fonte difícil de "enxergar".
Alguém conseguiu algo interessante pra isso?

Notas:
- A estrutura do DBF parece não resolver, porque é mais limitada
- O índice faz parte da estrutura no SQL
- O único inconveniente assim é gastar espaço de string no EXE, nem sei uma alteração vai economizar alguma coisa no resultado final.

Facilitar criação de tabela no fonte

MensagemEnviado: 13 Set 2016 08:32
por rubens
Quintas...

Ignorância minha, isso aí por exemplo não poderia ser utilizado em STORE PROCEDURES ?

Rubens

Facilitar criação de tabela no fonte

MensagemEnviado: 13 Set 2016 09:35
por JoséQuintas
A intenção é: criou a base de dados pronto, o aplicativo faz o resto, sem intervenção manual.
Pra existirem as stored procedures, precisaria algo mais já na base de dados.
(sem falar que ainda não aprendi isso.... rs)

Facilitar criação de tabela no fonte

MensagemEnviado: 13 Set 2016 11:21
por JoséQuintas
Só voltando um pouco ao assunto:

Minha intenção é o aplicativo continuar criando tudo do zero.
Praticamente só defino o nome do banco de dados, usuário e senha, e o aplicativo faz o resto.
Tá equivalente a:
IF .NOT. File( "arquivo.dbf" )
   dbCreate( "arquivo.dbf", ... )
ENDIF
IF .NOT. File( "arquivo.cdx" )
   INDEX ON ...
ENDIF


Pra usar stored procedures (rotinas dentro da base), depende das rotinas existirem, o que seria equivalente a já existir um banco de dados com conteúdo.
Mas e aí? Como essas stored procedures chegariam ao banco de dados? Se for pra copiar uma base pronta, tanto faz se for stored procedure ou a base com as tabelas prontas.

Facilitar criação de tabela no fonte

MensagemEnviado: 13 Set 2016 14:05
por alxsts
Olá!

Um recurso que pode ser usado para evitar as concatenações de strings e melhorar a legibilidade deste tipo de código é o comando TEXT. Veja exemplo:
//------------------------------------------------------------------------------

STATIC FUNCTION ScriptGenerator()

   LOCAL cSql As Character
   LOCAL aRet As Array

   aRet := {}

   TEXT INTO cSql
      USE [Harbour]

      /****** Object:  Table [dbo].[tbAddressType]    Script Date: 09/04/2014 20:18:23 ******/
      SET ANSI_NULLS ON
      SET QUOTED_IDENTIFIER ON
      SET ANSI_PADDING ON

      CREATE TABLE [dbo].[tbAddressType](
         [idAddressType] [int] IDENTITY(1,1) NOT NULL,
         [dsAddressType] [varchar](20) NOT NULL,
       CONSTRAINT [XPKtbAddressType] PRIMARY KEY CLUSTERED
      (
         [idAddressType] ASC
      )WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
      ) ON [PRIMARY]

      SET ANSI_PADDING OFF
   ENDTEXT

   AAdd( aRet, cSql )

   // demais tabelas...

RETURN aRet
   //---------------------------------------------------------------------------


Depois executa cada um dos scripts:
TablesGenerator( ScriptGenerator() )


//------------------------------------------------------------------------------

STATIC FUNCTION TablesGenerator( aScripts )

   LOCAL cSql As Character
   LOCAL lRet As Logical

   lRet := .F.
     
   Try
      oCn:Open()

      For Each cSql In aScripts
         oCn:Execute( cSql )
      Next

      lRet := .T.
     
   Catch oErr
      Throw( oErr )
   Finally
      If oCn:state() = adStateOpen
         oCn:Close()
      Endif
   End

RETURN lRet
//------------------------------------------------------------------------------

A sintaxe acima é do MS SQL Server.

Facilitar criação de tabela no fonte

MensagemEnviado: 13 Set 2016 18:31
por JoséQuintas
Não deu certo, mas lembrando que a string vai ficar maior ainda, já que até os espaços em branco iriam contar.
Tentei isto:

STATIC FUNCTION JPPREHISCreateMySql( cTxt )

   TEXT INTO cTxt
      CREATE TABLE IF NOT EXISTS JPPREHIS (
      PHID     INT(11)      NOT NULL AUTO_INCREMENT,
      PHITEM   VARCHAR(6)   NOT NULL DEFAULT '',
      PHCADAS  VARCHAR(6)   NOT NULL DEFAULT '',
      PHFORPAG VARCHAR(6)   NOT NULL DEFAULT '',
      PHDATA   DATE         NULL,
      PHHORA   VARCHAR(8)   NOT NULL DEFAULT '',
      PHVALOR  DOUBLE(16,4) NOT NULL DEFAULT '0.0',
      PHOBS    VARCHAR(60)  NOT NULL DEFAULT '',
      PHINFINC VARCHAR(80)  NOT NULL DEFAULT '',
      PHINFALT VARCHAR(80)  NOT NULL DEFAULT '',
      PRIMARY KEY    ( PHID ),
      INDEX IDXITEM  ( PHITEM, PHCADAS, PHFORPAG, PHDATA DESC, PHHORA DESC ),
      INDEX IDXCADAS ( PHCADAS, PHITEM, PHFORPAG, PHDATA ),
      INDEX IDXDATA  ( PHDATA, PHITEM, PHCADAS, PHFORPAG )
      ) COLLATE=latin1_swedish_ci ENGINE=InnoDB
   ENDTEXT

   RETURN cTxt


Como não aceita a TEXT INTO cTxt, dá erro em todo resto.

rccriamysql.prg:632: error E0030 Syntax error "syntax error at 'INTO'"

rccriamysql.prg:633: error E0030 Syntax error "syntax error at 'TABLE'"

rccriamysql.prg:634: error E0030 Syntax error "syntax error at 'INT'"

rccriamysql.prg:635: error E0030 Syntax error "syntax error at 'VARCHAR'"

rccriamysql.prg:636: error E0030 Syntax error "syntax error at 'VARCHAR'"

rccriamysql.prg:637: error E0030 Syntax error "syntax error at 'VARCHAR'"

Facilitar criação de tabela no fonte

MensagemEnviado: 13 Set 2016 18:41
por JoséQuintas
Talvez uma opção seja incluir todos os comandos como resource.
Vou testar depois.

Facilitar criação de tabela no fonte

MensagemEnviado: 13 Set 2016 19:10
por alxsts
Olá!

Funciona perfeitamente com o Harbour 3.2. Certamente o problema de não aceitar TEXT INTO é no Harbour 3.4. Precisa ver o que o Viktor pode fazer para compatibilizar as duas versões.

Facilitar criação de tabela no fonte

MensagemEnviado: 13 Set 2016 20:00
por JoséQuintas
Correção: Isso é do xHarbour.

#include "hbcompat.ch"

PROCEDURE Main

LOCAL x

TEXT INTO x
   sdfsfdsdfds
   sdfsdfsdsfds
   sdfsdfdsfsdfds
ENDTEXT

CLS
? x

RETURN


hbmk2 test xhb.hbc

Facilitar criação de tabela no fonte

MensagemEnviado: 23 Set 2016 13:03
por alxsts
Olá!

Este código que postei foi escrito faz anos e nem me lembrava deste include (hbCompat.ch).
JoséQuintas escreveu:Correção: Isso é do xHarbour.

Correto. Na minha opinião, este fato não inviabiliza o uso do comando, que é uma tradução conseguida através do pré processador, como todos os comandos xBase.
   /* TEXT INTO <varname> */
   #xcommand TEXT INTO <v> => #pragma __text|<v>+=%s+hb_eol();<v>:=""
Penso que o ganho em legibilidade justifica o uso (evita aquelas concatenações de strings horrorosas).

Facilitar criação de tabela no fonte

MensagemEnviado: 06 Out 2016 23:53
por wmanesco
Olá pessoal!

Recentemente venho desenvolvendo uma classe com este intuito, de criar tabelas. Ainda não está finalizada mas está criando tabelas simples e não possui metodos para criar indices ainda.

Apenas para exemplificar vou mostrar como seria o uso e caso alguem se interesse coloco o código para download em algum local.
Lembrando que não está tão robusto.

A idéia é a seguinte:

   oClientes := DBTables():new( "clientes" )

   oClientes:int("id"):notNull():autoIncrement():uniqueIndex():primaryKey() //Adiciona um campo INT not null, auto increment, unique Index e primary Key.
   oClientes:string( "razao_social", 100 ):notNull() //adiciona um VARCHAR de tamanho 100 e not null
   oClientes:string( "telefone", 11 ) adiciona um VARCHAR de tamanho 11
   oClientes:string( "ie", 11 )
   oClientes:string( "cnpj", 15 )
   oClientes:string( "endereco", 150 )
   oClientes:string( "cep", 8 )
   oClientes:date("datacadastro") // adiciona um campo data
   oClientes:decimal("limite", 11, 2) // adiciona um decimal 11, 2 )
   oClientes:create()


Funciona assim: Cada vez que chamo um comando ele vai guardando os campos em um array de objetos (cada tipo é um objeto), chamando o create() corre o array e monta uma string de inserção no banco.

Estou trabalhando quando é possível para criar um método de update, assim seria muito simples alterar campos nas tabelas sem precisar ficando alter table, mas estou encontrando algumas dificuldades de desenvolver este método.

Desenvolvi com a idéia base com que funciona um framework para php(que esqueci o nome agora kk)

Abraços.

Facilitar criação de tabela no fonte

MensagemEnviado: 07 Out 2016 00:05
por wmanesco
Lembrei o nome do framework php, é laravel!

Facilitar criação de tabela no fonte

MensagemEnviado: 07 Out 2016 10:13
por jairfab
wmanesco, tem como você disponibilizar eu fiquei interessado pois estou fazendo a conversão de um sistema DBF para banco de dados FIREBIRD e tenho muitas tabelas para ser criadas

Facilitar criação de tabela no fonte

MensagemEnviado: 07 Out 2016 11:37
por wmanesco
Assim que conseguir subir eu post o link aqui!

Facilitar criação de tabela no fonte

MensagemEnviado: 07 Out 2016 13:40
por wmanesco

Facilitar criação de tabela no fonte

MensagemEnviado: 07 Out 2016 16:04
por JoséQuintas
Tava pensando em algo menos radical, tipo isto:

cString := "CREATE TABLE CLIENTES ( " + ;
   CampoMySql( "CODIGO", "I" , 11, 0, .F., "AUTO_INCREMENT" ) + ;
   CampoMySql( "NOME", "V", 100, 0, .T., "DEFAULT ''" ) + ")"

FUNCTION CampoMySql( cName, cType, nLen, nDec, lNull, cCompl )

   LOCAL cText := ""

   cText += cName
   DO CASE
   CASE cType == "C"; cText += "CHAR"
   CASE cType == "D"; cText += "DECIMAL"
   CASE cType == "I" ; cText += "INT"
   CASE cType == "V", cText += "VARCHAR"
   ENDCASE
   cText += " (" + Ltrim(Str(nLen)) + iif( nDecimal == 0, "", ", " + Ltrim( Str(nDecimal) ) ) + ") "
   cText += " " + iif( lNull, "NULL", "NOT NULL" )
   IF ! Empty( cCompl )
      cText += cCompl
   ENDIF
   RETURN cText


Só pra deixar as partes alinhadas, sem encher de string no EXE.
Mesmo assim, parece que não compensa.

Facilitar criação de tabela no fonte

MensagemEnviado: 07 Out 2016 21:25
por wmanesco
Tem opção de trabalhar com array, já vi uma vez mas não lembro certinho a estrutura mas a idéia é a seguinte:

FUNCTION CriaTbelas()

   LOCAL aTabela

   FOR EACH aTabela IN EstruturaTabelasSistema()
      //Aqui seria desenvolvido o código montando a string.
   NEXT

RETURN

/****************************************************/
FUNCTION EstruturaTabelasSistema()

   LOCAL aTabelas := {}, aTabela

   //ESTRUTURA
   //NOME, TIPO, TAMANHO, DECIMAL, AUTO INCREMENT (pode ser adicionado mais campos tipo um campo para dizer se é primary key)

   aTabela := {"CLIENTES", {"ID"      , "N", 10, 0, .T. },;
                                       {"NOME", "C", 50, 0, .F. };
                   }

   AAdd(aTabelas, aTabela)

RETURN aTabelas



Algo neste sentido acho que fica bom também sem ser tão radical

Facilitar criação de tabela no fonte

MensagemEnviado: 07 Dez 2016 14:39
por JoséQuintas
Como eu já comentei uma vez:

A parte mais crítica, aonde temos mais pressa, é pra resolver bugs.
Então o fonte tem que estar direcionado a ver rápido do que se trata.
Na dúvida sobre qual fica melhor, melhor deixar o que permite resolver bugs rapidamente.
Ao não perder tempo com bugs, sobra mais tempo pra criação/melhoria.

Também é interessante já criar estrutura e índices de uma vez, assim qualquer coisa errada já aparece o alerta.

Por enquanto ainda vou mantendo o original do início do post.