FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour MYSQL / MARIA MaintenanceTable(oCn, aNewStr, cTableName)
Posts: 181
Joined: Thu Apr 17, 2008 02:38 PM
MYSQL / MARIA MaintenanceTable(oCn, aNewStr, cTableName)
Posted: Wed Apr 19, 2023 09:34 PM
Hi all,

I wonder if there is a method to be able to maintain tables without having to use something made by me,
I'm an absolute beginner
Code (fw): Select all Collapse
*------------------------------------------------------------------------------------------------
FUNCTION MaintenanceTable(oCn, aNewStr, cTableName)
*------------------------------------------------------------------------------------------------

   LOCAL aOldStr     AS ARRAY  
   LOCAL aTmpStr     AS ARRAY  
   LOCAL aResOld     AS ARRAY  
   LOCAL aResTmp     AS ARRAY  
   LOCAL aInsert     AS ARRAY  
   LOCAL aChange     AS ARRAY  
   LOCAL aDelete     AS ARRAY  
   LOCAL nAt         AS NUMERIC
   LOCAL nLenOld     AS NUMERIC
   LOCAL nLenTmp     AS NUMERIC
   LOCAL nI1         AS NUMERIC
   LOCAL nResult     AS NUMERIC
   LOCAL oRs         AS OBJECT
   LOCAL oField      AS OBJECT
   LOCAL cTableTemp  AS CHARACTER

   aOldStr := {}  
   aTmpStr := {}  
   aResOld := {}  
   aResTmp := {}  
   aInsert := {}  
   aChange := {}  
   aDelete := {}  
   nAt     := 0
   nLenOld := 0
   nLenTmp := 0
   nI1     := 0
   nResult := 0
   cTableTemp := "TempTable"

   *--------------------------------------------------------------------------------------------
   *- Verifica se esiste la tabella, se non esiste viene creata
   *- Check if the table exists, if it doesn't exist it is created
   *--------------------------------------------------------------------------------------------
   
   IF .not. oCn:TableExists(cTableName)
      oCn:createTable( cTableName, aNewStr, .F., "utf8" )
      RETURN .T.
   ENDIF

   *--------------------------------------------------------------------------------------------
   *- Rilevazione parametri dalla vecchia struttura
   *- Parameter acquisition from the old structure
   *--------------------------------------------------------------------------------------------
   
   aOldStr := oCn:TableStructure(cTableName)
   nLenOld := LEN(aOldStr)
   oRs     := oCn:RowSet( "select * from " + cTableName)  

   FOR nI1 := 1 TO nlenOld
       nResult := 0
       oField  := oRs:Fields( nI1 - 1 ) 
       nResult += oField:flags  
       nResult += IF(oField:lNoNull  , 1, 0)
       nResult += IF(oField:lReadOnly, 1, 0)
       nResult += IF(oField:lAutoInc , 1, 0)
       nResult += IF(oField:lPrimary , 1, 0)
       nResult += IF(oField:lUnique  , 1, 0)
       nResult += IF(oField:lKey     , 1, 0)
       nResult += IF(oField:lNoNull  , 1, 0)
       nResult += IF(oField:lBinary  , 1, 0)
       nResult += oField:Len2
       IF aOldStr[nI1,2] == "m"
          aOldStr[nI1,3] := 10
       ENDIF
       aadd(aResOld, {aOldStr[nI1,1], aOldStr[nI1,2], aOldStr[nI1,3], aOldStr[nI1,4], aOldStr[nI1,5], nResult})
   NEXT  

   oRs:close()
   
   *--------------------------------------------------------------------------------------------
   *- Creazione della nuova struttura tramite una tabella temporanea
   *- Creation of the new structure using a temporary table
   *--------------------------------------------------------------------------------------------

   oCn:DropTable(cTableTemp)
   
   oCn:CreateTable(cTableTemp, aNewStr, .F., "utf8")
   aTmpStr := oCn:TableStructure(cTableTemp)
   nLenTmp := LEN(aTmpStr)
   oRs     := oCn:RowSet( "select * from " + cTableTemp)  

   FOR nI1 := 1 TO nlenTmp
       nResult := 0
       oField  := oRs:Fields( nI1 - 1 ) 
       nResult += oField:flags  
       nResult += IF(oField:lNoNull  , 1, 0)
       nResult += IF(oField:lReadOnly, 1, 0)
       nResult += IF(oField:lAutoInc , 1, 0)
       nResult += IF(oField:lPrimary , 1, 0)
       nResult += IF(oField:lUnique  , 1, 0)
       nResult += IF(oField:lKey     , 1, 0)
       nResult += IF(oField:lNoNull  , 1, 0)
       nResult += IF(oField:lBinary  , 1, 0)
       nResult += oField:Len2
       IF aTmpStr[nI1,2] == "m"
          aTmpStr[nI1,3] := 10
       ENDIF
       aadd(aResTmp, {aTmpStr[nI1,1], aTmpStr[nI1,2], aTmpStr[nI1,3], aTmpStr[nI1,4], aTmpStr[nI1,5], nResult, aNewStr[nI1]})
   NEXT  

   oRs:close()
   oCn:DropTable(cTableTemp)

   *--------------------------------------------------------------------------------------------
   *- Preparazione array aInsert, aChange, aDelete
   *- Array preparation aInsert, aChange, aDelete
   *--------------------------------------------------------------------------------------------

   FOR nI1 := 1 TO LEN(aResTmp)

      *--------------------------------------------------------------------------------------------
      *- Un campo della nuova struttura viene ricercato nella vecchia struttura se non è trovato
      *- il campo è da inserire, se invece è trovato si procede con la ricerca della differenze  
      *- a livello di 'TIPO', 'LEN', 'DEC', condizioni SQL, se ci sono differenze si procede con
      *- la modifica. 
      *-                                                                             
      *- A field in the new structure is searched for in the old structure if it is not found
      *- the field is to be inserted, if instead it is found we proceed with the search for the 
      *- differences at the level of 'TYPE', 'LEN', 'DEC', SQL conditions, etc. if there are 
      *- differences, proceed with AlterColumn.
      *--------------------------------------------------------------------------------------------

       nAt := AScan(aResOld, {|a| a[1] = aResTmp[nI1, 1]})
   
       IF nAt = 0                   
          aAdd(aInsert, aResTmp[nI1,7])
       ELSE
          IF .not. aResOld[nAt,2] == aResTmp[nI1,2] .OR. ;
             .not. aResOld[nAt,3] == aResTmp[nI1,3] .OR. ;
             .not. aResOld[nAt,4] == aResTmp[nI1,4] .OR. ;
             .not. aResOld[nAt,5] == aResTmp[nI1,5] .OR. ;
             .not. aResOld[nAt,6] == aResTmp[nI1,6]  
             aAdd(aChange, aResTmp[nI1,7])
          ENDIF
       ENDIF  
   
   NEXT

   *--------------------------------------------------------------------------------------------
   *- Se nella vecchia struttura vi è un campo non più presente nella nuova struttura il
   *- campo è da eliminare.
   *-
   *- If in the old structure there is a field that is no longer present in the new structure  
   *- the field is to be deleted.
   *--------------------------------------------------------------------------------------------
      
   FOR nI1 := 1 TO LEN(aResOld)

       nAt := AScan(aResTmp, {|a| a[1] = aResOld[nI1, 1]})

       IF nAt = 0   
          aAdd(aDelete, aResOld[nI1,1])
       ENDIF  

   NEXT  

   *--------------------------------------------------------------------------------------------
   *- Azione sul database tramite aInsert, aChange, aDelete
   *- Action on the database through aInsert, aChange, aDelete
   *--------------------------------------------------------------------------------------------

   oCn:lSilent := .T.
   
   IF .not. EMPTY(aInsert) 
      FOR nI1 := 1 TO LEN(aInsert)
          MsgAlert("Inserimento colonna : " + aInsert[nI1,1] + " sulla tabella : " + cTableName, "Avviso")       
          oCn:AddColumn( cTableName, aInsert[nI1] )                    
      NEXT
   ENDIF
   
   IF .not. EMPTY(aChange) 
      FOR nI1 := 1 TO LEN(aChange)
          MsgAlert("Variazione colonna : " + aChange[nI1,1] + " sulla tabella : " + cTableName, "Avviso")       
          oCn:Execute("ALTER TABLE " + cTableName + " DROP INDEX IF EXISTS " + aChange[nI1,1])   
          oCn:AlterColumn( cTableName, aChange[nI1] )
      NEXT
   ENDIF
   
   IF .not. EMPTY(aDelete)  
      FOR nI1 := 1 TO LEN(aDelete)
          MsgAlert("Cancellazione colonna : " + aDelete[nI1] + " sulla tabella : " + cTableName, "Avviso")       
          oCn:Execute("ALTER TABLE " + cTableName + " DROP COLUMN IF EXISTS " + aDelete[nI1])
      NEXT
   ENDIF

   oCn:lSilent := .F.
      
RETURN .T.
TIA Maurizio Menabue
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: MYSQL / MARIA MaintenanceTable(oCn, aNewStr, cTableName)
Posted: Thu Apr 20, 2023 01:32 AM

Maurizio:

May be these programs can help you

WorkBench

NaviCat

Heidi

DBeaver

Regards

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 181
Joined: Thu Apr 17, 2008 02:38 PM
Re: MYSQL / MARIA MaintenanceTable(oCn, aNewStr, cTableName)
Posted: Thu Apr 20, 2023 07:46 AM
hi Armando
I use heidi as a program similar to the old dbu because the new fivedbu is not complete yet.
I intended a method of a class to be able to make changes in a table from within the exe under development eg:
Code (fw): Select all Collapse
*------------------------------------------------------------------------------------------
*- Table : IVA Old structure
*------------------------------------------------------------------------------------------
    {"IVA_COD", "C", 2, 0, "PRIMARY, NOT NULL, "}
    {"IVA_DES", "C", 80, 0, "UNIQUE, NOT NULL, "}
    {"IVA_IND", "N", 2, 0, " NOT NULL, "} <----- Col/field delete

*------------------------------------------------------------------------------------------
*- Table : IVA New structure
*------------------------------------------------------------------------------------------
   aStrIva := {}
   aadd(StrIva, {"IVA_COD", "C", 2, 0, "PRIMARY, NOT NULL, "})
   aadd(StrIva, {"IVA_DES", "C", 120, 0, "UNIQUE, NOT NULL, "}) <-------- Modify len col/field
   aadd(StrIva, {"IVA_PRC", "N", 2, 0, "NOT NULL,  DEFAULT 0"}) <-------- New col/Field
 
  IF oCn:MaintenceTable(oCn, aStrIva, "IVA')
     MsgAlert("the table has been successfully modified !", "Alert")
  ENDIF
  ....
TIA

Continue the discussion