hbmsql

  Previous topic Next topic JavaScript is required for the print function Mail us feedback on this topic! Mail us feedback on this topic!  
c:\harbour\contrib\hbmsql
msql.c
TypeFunctionSourceLine
HB_FUNCMSQLCONNEC(void)
HB_FUNC( MSQLCONNEC ) /* int msqlConnect(char *) */
{
   hb_retni( msqlConnect( hb_parc( 1 ) ) );
}
msql.c66
HB_FUNCMSQLCLOSE(void)
HB_FUNC( MSQLCLOSE ) /* void msqlClose(int) */
{
   msqlClose( hb_parni( 1 ) );
}
msql.c71
HB_FUNCMSQLSELECT(void)
HB_FUNC( MSQLSELECT ) /* int msqlSelectDB(int, char *) */
{
   hb_retni( msqlSelectDB( hb_parni( 1 ), hb_parc( 2 ) ) );
}
msql.c76
HB_FUNCMSQLQUERY(void)
HB_FUNC( MSQLQUERY ) /* int msqlQuery(int, char *) */
{
   hb_retni( msqlQuery( hb_parni( 1 ), hb_parc( 2 ) ) );
}
msql.c81
HB_FUNCMSQLSTORER(void)
HB_FUNC( MSQLSTORER ) /* m_result *msqlStoreResult() */
{
   HB_RETPTR( ( void * ) msqlStoreResult() );
}
msql.c86
HB_FUNCMSQLFREER(void)
HB_FUNC( MSQLFREER ) /* void msqlFreeResult(m_result *) */
{
   msqlFreeResult( ( m_result * ) HB_PARPTR( 1 ) );
}
msql.c91
HB_FUNCMSQLFETCHR(void)
HB_FUNC( MSQLFETCHR ) /* m_row msqlFetchRow(m_result *, int) */
{
   m_result * mresult = ( m_result * ) HB_PARPTR( 1 );
   int num_fields = hb_parnl( 2 );
   PHB_ITEM aRow = hb_itemArrayNew( num_fields );
   m_row mrow = msqlFetchRow( mresult );
   int i;

   for( i = 0; i < num_fields; i++ )
      hb_arraySetC( aRow, i + 1, mrow[ i ] );

   hb_itemReturnRelease( aRow );
}
msql.c96
HB_FUNCMSQLDATASE(void)
HB_FUNC( MSQLDATASE ) /* void msqlDataSeek(m_result *, int) */
{
   msqlDataSeek( ( m_result * ) HB_PARPTR( 1 ), hb_parni( 2 ) );
}
msql.c111
HB_FUNCMSQLNUMROW(void)
HB_FUNC( MSQLNUMROW ) /* int msqlNumRows(m_result *) */
{
   hb_retni( msqlNumRows( ( ( m_result * ) HB_PARPTR( 1 ) ) ) );
}
msql.c116
HB_FUNCMSQLFETCHF(void)
HB_FUNC( MSQLFETCHF ) /* m_field *msqlFetchField(m_result *) */
{
   m_field * mfield = msqlFetchField( ( m_result * ) HB_PARPTR( 1 ) );
   PHB_ITEM aField = hb_itemArrayNew( 5 ); /* NOTE: m_field structure of mSQL 2.x has 5 members */

   if( mfield )
   {
      hb_arraySetC(  aField, 1, mfield->name );
      hb_arraySetC(  aField, 2, mfield->table );
      hb_arraySetNL( aField, 3, mfield->type );
      hb_arraySetNL( aField, 4, mfield->length );
      hb_arraySetNL( aField, 5, mfield->flags );
   }

   hb_itemReturnRelease( aField );
}
msql.c121
HB_FUNCMSQLFIELDS(void)
HB_FUNC( MSQLFIELDS ) /* void msqlFieldSeek(m_result *, int) */
{
   msqlFieldSeek( ( m_result * ) HB_PARPTR( 1 ), hb_parni( 2 ) );
}
msql.c138
HB_FUNCMSQLNUMFIE(void)
HB_FUNC( MSQLNUMFIE ) /* int msqlNumFields(m_result *) */
{
   hb_retni( msqlNumFields( ( ( m_result * ) HB_PARPTR( 1 ) ) ) );
}
msql.c143
HB_FUNCMSQLLISTFI(void)
HB_FUNC( MSQLLISTFI ) /* m_result *msqlListFields(int, char *); */
{
   HB_RETPTR( ( void * ) msqlListFields( hb_parni( 1 ), hb_parc( 2 ) ) );
}
msql.c148
HB_FUNCMSQLGETERR(void)
HB_FUNC( MSQLGETERR ) /* char *msqlGetErrMsg(char *); */
{
   hb_retc( msqlErrMsg );
}
msql.c153
HB_FUNCMSQLLISTDB(void)
HB_FUNC( MSQLLISTDB ) /* m_result * msqlListDBs(int); */
{
   int sock = hb_parnl( 1 );
   m_result * mresult = msqlListDBs( sock );
   long nr = msqlNumRows( mresult );
   PHB_ITEM aDBs = hb_itemArrayNew( nr );
   long i;

   for( i = 0; i < nr; i++ )
      hb_arraySetC( aDBs, i + 1, msqlFetchRow( mresult )[ 0 ] );

   msqlFreeResult( mresult );
   hb_itemReturnRelease( aDBs );
}
msql.c158
HB_FUNCMSQLLISTTA(void)
HB_FUNC( MSQLLISTTA ) /* m_result * msqlListTables(int); */
{
   int sock = hb_parnl( 1 );
   m_result * mresult = msqlListTables( sock );
   long nr = msqlNumRows( mresult );
   PHB_ITEM aTables = hb_itemArrayNew( nr );
   long i;

   for( i = 0; i < nr; i++ )
      hb_arraySetC( aTables, i + 1, msqlFetchRow( mresult )[ 0 ] );

   msqlFreeResult( mresult );
   hb_itemReturnRelease( aTables );
}
msql.c173
tmsql.prg
TypeFunctionSourceLine
CLASSTmSQLRow
CLASS TmSQLRow

   DATA  aRow              // a single row of answer
   DATA  aDirty            // array of booleans set to .T. if corresponding field of aRow has been changed
   DATA  aFieldStruct      // type of each field
   DATA  cTable            // Name of table containing this row, empty if TmSQLQuery returned this row
   DATA  nRowID            // Record Number inside mSQL table. Used by Update() method of TmSQLTable

   METHOD   New(aRow, aFStruct, cTableName, lRowID)     // Create a new Row object and handle hidden _rowid field

   METHOD   FieldGet(nNum)                      // Same as clipper ones
   METHOD   FieldPut(nNum, Value)

   METHOD   FieldName(nPosition)
   METHOD   FieldPos(cFieldName)

ENDCLASS
tmsql.prg61
TMSQLROW:METHODNew(aRow, aFStruct, cTableName, lRowID) CLASS TmSQLRow
METHOD New(aRow, aFStruct, cTableName, lRowID) CLASS TmSQLRow

   default cTableName to ""
   default aFStruct to {}
   default lRowID to .F.

   ::cTable := cTableName
   ::aFieldStruct := aFStruct

   // if first field is _rowid I'm inside a TmSQLTable, so remove this low level
   // info from list of fields.
   if lRowID
      ::nRowID := aRow[1]

      // remove first field (copying from second)
      ::aRow := Array(Len(aRow) - 1)
      ACopy(aRow, ::aRow, 2)

   else
      ::aRow := aRow
      ::aFieldStruct := aFStruct
      ::nRowID := -1
   endif

   ::aDirty := Array(Len(::aRow))
   AFill(::aDirty, .F.)

return Self
tmsql.prg80
TMSQLROW:METHODFieldGet(nNum) CLASS TmSQLRow
METHOD FieldGet(nNum) CLASS TmSQLRow

   if nNum > 0 .AND. nNum <= Len(::aRow)
      return ::aRow[nNum]
   endif

return nil
tmsql.prg110
TMSQLROW:METHODFieldPut(nNum, Value) CLASS TmSQLRow
METHOD FieldPut(nNum, Value) CLASS TmSQLRow

   if nNum > 0 .AND. nNum <= Len(::aRow)
      if Valtype(Value) == Valtype(::aRow[nNum]) .OR. Empty(::aRow[nNum])
         // if it's a char field encode singole quotes
         if ValType(Value) == "C"
            ::aRow[nNum] := StrTran(Value, "'", "\'")
         else
            ::aRow[nNum] := Value
         endif
         ::aDirty[nNum] := .T.
         return Value
      endif
   endif

return nil
tmsql.prg119
TMSQLROW:METHODFieldPos(cFieldName) CLASS TmSQLRow
METHOD FieldPos(cFieldName) CLASS TmSQLRow

   local cUpperName, nPos := 1

   cUpperName := Upper(cFieldName)

   /* NOTE: this code block kills harbour if called a few thousand times
   nPos := AScan(::aFieldStruct, {|aItem| iif(Upper(aItem[MSQL_FS_NAME]) == cUpperName, .T., .F.)})
   */

   while nPos <= Len(::aFieldStruct)
      if Upper(::aFieldStruct[nPos][MSQL_FS_NAME]) == cUpperName
         exit
      endif
      nPos++
   enddo

return nPos
tmsql.prg138
TMSQLROW:METHODFieldName(nPosition) CLASS TmSQLRow
METHOD FieldName(nPosition) CLASS TmSQLRow

   if nPosition >=1 .AND. nPosition <= Len(::aFieldStruct)
      return ::aFieldStruct[nPosition][MSQL_FS_NAME]
   endif

return ""
tmsql.prg159
CLASSTmSQLQuery
CLASS TmSQLQuery

   DATA  nSocket           // connection handle to mSQL server
   DATA  nResultHandle     // result handle received from mSQL

   DATA  cQuery            // copy of query that generated this object

   DATA  nNumRows          // number of rows available on answer NOTE msql is 0 based
   DATA  nCurRow           // I'm currently over row number

   DATA  nNumFields        // how many fields per row (including hidden _rowID)
   DATA  aFieldStruct      // type of each field, a copy is here a copy inside each row

   DATA  lRowID            // .T. if query has field _rowID
   DATA  lError            // .T. if last operation failed

   METHOD   New(nSocket, cQuery)       // New query object
   METHOD   Destroy()

   METHOD   GetRow(nRow)               // return Row n of answer

   METHOD   Skip(nRows)                // Same as clipper ones
tmsql.prg170
TMSQLQUERY:METHODBof()
   METHOD   Bof() INLINE ::nCurRow == 1
tmsql.prg193
TMSQLQUERY:METHODEof()
   METHOD   Eof() INLINE ::nCurRow > ::nNumRows
tmsql.prg194
TMSQLQUERY:METHODRecNo()
   METHOD   RecNo() INLINE ::nCurRow
tmsql.prg195
TMSQLQUERY:METHODLastRec()
   METHOD   LastRec() INLINE ::nNumRows

   METHOD   FCount()
tmsql.prg196
TMSQLQUERY:METHODNetErr()
   METHOD   NetErr() INLINE ::lError         // Returns .T. if something went wrong
   METHOD   Error()                          // Returns textual description of last error and clears ::lError

ENDCLASS
tmsql.prg200
TMSQLQUERY:METHODNew(nSocket, cQuery) CLASS TmSQLQuery
METHOD New(nSocket, cQuery) CLASS TmSQLQuery

   local nI, aField

   ::aFieldStruct := {}
   ::nSocket := nSocket
   ::cQuery := cQuery
   ::nNumRows := msqlQuery(nSocket, cQuery)
   ::nCurRow := 1
   ::lRowID := .F.
   ::lError := .F.

   if ::nNumRows >= 0

      ::nResultHandle := msqlStoreR()
      ::nNumFields := msqlNumFie(::nResultHandle)

      for nI := 1 to ::nNumFields

         aField := msqlFetchF(::nResultHandle)

         if Upper(aField[MSQL_FS_NAME]) == "_ROWID"
            ::lRowID := .T.
         else
            AAdd(::aFieldStruct, aField)
         endif
      next
   else

      ::nResultHandle := nil
      ::nNumFields := 0
      ::lError := .T.
   endif

return Self
tmsql.prg206
TMSQLQUERY:METHODSkip(nRows) CLASS TmSQLQuery
METHOD Skip(nRows) CLASS TmSQLQuery

   // NOTE: mSQL row count starts from 0
   default nRows to 1

   if nRows == 0
      // No move
   elseif nRows < 0
      // Negative movement
      ::nCurRow := Max(::nCurRow - nRows, 1)
   else
      // positive movement
      ::nCurRow := Min(::nCurRow + nRows, ::nNumRows + 1)
   endif

   msqlDataSe(::nResultHandle, ::nCurRow - 1)

return Self
tmsql.prg244
STATIC FUNCTIONNMonth(cMonthValue)
static function NMonth(cMonthValue)

   static cMonths := {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dec" }

   local nMonth := AScan(cMonths, cMonthValue)

return PadL(nMonth, 2, "0")
tmsql.prg265
TMSQLQUERY:METHODGetRow(nRow) CLASS TmSQLQuery
METHOD GetRow(nRow) CLASS TmSQLQuery

   local aRow := NIL
   local oRow := NIL
   local i

   default nRow to 0

   if ::nResultHandle != NIL
      if nRow >= 1 .AND. nRow <= ::nNumRows

         // NOTE: row count starts from 0
         msqlDataSe(::nResultHandle, nRow - 1)
         ::nCurRow := nRow
      else
         ::nCurRow++
      endif

      aRow := msqlFetchR(::nResultHandle, ::nNumFields)

      if aRow != NIL

         if ::lRowID
            aRow[1] := Val(aRow[1])
         endif

         // Convert answer from text field to correct clipper types
         for i := iif(::lRowID, 2, 1) to ::nNumFields
             do case
             case ::aFieldStruct[iif(::lRowID, i - 1, i)][MSQL_FS_TYPE] == MSQL_UINT_TYPE
               aRow[i] := iif(Val(aRow[i]) == 0, .F., .T.)

             case ::aFieldStruct[iif(::lRowID, i - 1, i)][MSQL_FS_TYPE] == MSQL_INT_TYPE
               aRow[i] := Val(aRow[i])

             case ::aFieldStruct[iif(::lRowID, i - 1, i)][MSQL_FS_TYPE] == MSQL_REAL_TYPE
               aRow[i] := Val(aRow[i])

             case ::aFieldStruct[iif(::lRowID, i - 1, i)][MSQL_FS_TYPE] == MSQL_DATE_TYPE
               if Empty(aRow[i])
                  aRow[i] := CToD("")
               else
                  // Date format MM/DD/YYYY
                  aRow[i] := CToD(NMonth(__StrToken(aRow[i], 2, "-")) + "/" + __StrToken(aRow[i], 1, "-") + "/" + __StrToken(aRow[i], 3, "-"))
               endif
             otherwise
             endcase
         next

         oRow := TmSQLRow():New(aRow, ::aFieldStruct,, ::lRowID)
      endif
   endif

return iif(aRow == NIL, NIL, oRow)
tmsql.prg275
TMSQLQUERY:METHODDestroy() CLASS TmSQLQuery
METHOD Destroy() CLASS TmSQLQuery

   msqlFreeR(::nResultHandle)

return Self
tmsql.prg332
TMSQLQUERY:METHODFCount() CLASS TmSQLQuery
METHOD FCount() CLASS TmSQLQuery

return ::nNumFields - iif(::lRowID, 1, 0)
tmsql.prg339
TMSQLQUERY:METHODError() CLASS TmSQLQuery
METHOD Error() CLASS TmSQLQuery

   ::lError := .F.

return msqlGetErr()
tmsql.prg344
CLASSTmSQLTable FROM TmSQLQuery
CLASS TmSQLTable FROM TmSQLQuery

   DATA  cTable               // name of table

   METHOD   New(nSocket, cQuery, cTableName)
   METHOD   GetRow(nRow)

   METHOD   Update(oRow)      // Gets an oRow and updates changed fields
   METHOD   Delete(oRow)      // Deletes passed row from table
   METHOD   Append(oRow)      // Inserts passed row into table
   METHOD   GetBlankRow()     // Returns an empty row with all available fields empty

ENDCLASS
tmsql.prg355
TMSQLTABLE:METHODNew(nSocket, cQuery, cTableName) CLASS TmSQLTable
METHOD New(nSocket, cQuery, cTableName) CLASS TmSQLTable

   local cTrimmedQuery, nRes, i, cFieldList := "SELECT _rowid, ", aField

   ::cTable := cTableName

   // Add _rowid to query, Update() method needs this field
   cTrimmedQuery := AllTrim(cQuery)

   // if it's a SELECT * I cannot add _rowid to query; I need to expand * to the full list of fields
   if __StrToken(cTrimmedQuery, 2, " ") == "*"

      nRes := msqlListFi(nSocket, cTableName)

      if !Empty( nRes )
         for i := 1 to msqlNumFie(nRes)
            aField := msqlFetchF(nRes)
            // don't count indexes as real fields
            if aField[MSQL_FS_TYPE] <= MSQL_LAST_REAL_TYPE
               cFieldList += aField[MSQL_FS_NAME] + ","
            endif
         next
         // remove last comma
         cFieldList := Left(cFieldList, Len(cFieldList) - 1)

         // remove SELECT
         cTrimmedQuery := StrTran(cTrimmedQuery, __StrToken(cTrimmedQuery, 1, " "), "")
         // remove *
         cTrimmedQuery := StrTran(cTrimmedQuery, __StrToken(cTrimmedQuery, 1, " "), "")
         cTrimmedQuery := cFieldList + cTrimmedQuery
         msqlFreeR(nRes)
      endif
   else
      cTrimmedQuery := StrTran(cTrimmedQuery, __StrToken(cTrimmedQuery, 1, " "), "SELECT _rowid, ")
   endif

   super:New(nSocket, cTrimmedQuery)

return Self
tmsql.prg370
TMSQLTABLE:METHODGetRow(nRow) CLASS TmSQLTable
METHOD GetRow(nRow) CLASS TmSQLTable

   local oRow := super:GetRow(nRow)

   if oRow != NIL
      oRow:cTable := ::cTable
   endif

return oRow
tmsql.prg411
TMSQLTABLE:METHODUpdate(oRow) CLASS TmSQLTable
METHOD Update(oRow) CLASS TmSQLTable

   local cUpdateQuery := "UPDATE " + ::cTable + " SET "
   local i, cField

   // is this a row of this table ?
   if oRow:cTable == ::cTable
      for i := 1 to Len(oRow:aRow)
         if oRow:aDirty[i]
            do case
            case Valtype(oRow:aRow[i]) == "N"
               cField := AllTrim(Str(oRow:aRow[i]))
               cUpdateQuery += oRow:aFieldStruct[i][MSQL_FS_NAME] + "=" + cField + ","

            case Valtype(oRow:aRow[i]) == "D"
               if !Empty(oRow:aRow[i])
                  // mSQL dates are like this 1-Oct-1900
                  cUpdateQuery += oRow:aFieldStruct[i][MSQL_FS_NAME] + "=" + "'" + Str(Day(oRow:aRow[i]), 2) + "-" + Left(CMonth(oRow:aRow[i]), 3) + "-" + Str(Year(oRow:aRow[i]), 4) +  "',"
               else
                  cUpdateQuery += oRow:aFieldStruct[i][MSQL_FS_NAME] + "=" + "'',"
               endif

            case Valtype(oRow:aRow[i]) == "C"
               cUpdateQuery += oRow:aFieldStruct[i][MSQL_FS_NAME] + "='" + oRow:aRow[i] + "',"

            case Valtype(oRow:aRow[i]) == "L"
               cField := AllTrim(Str(iif(oRow:aRow[i] == .F., 0, 1)))
               cUpdateQuery += oRow:aFieldStruct[i][MSQL_FS_NAME] + "=" + cField + ","

            otherwise
               cUpdateQuery += oRow:aFieldStruct[i][MSQL_FS_NAME] + "='',"

            endcase
         endif
      next

      // remove last comma
      cUpdateQuery := Left(cUpdateQuery, Len(cUpdateQuery) -1)

      cUpdateQuery += " WHERE _rowid=" + AllTrim(Str(oRow:nRowID))

      if msqlQuery(::nSocket, cUpdateQuery) == 1
         // All values are commited
         Afill(oRow:aDirty, .F.)
         return .T.
      else
         ::lError := .T.
      endif
   endif

return .F.
tmsql.prg423
TMSQLTABLE:METHODDelete(oRow) CLASS TmSQLTable
METHOD Delete(oRow) CLASS TmSQLTable

   local cDeleteQuery := "DELETE FROM " + ::cTable + " WHERE _rowid="

   // is this a row of this table ?
   if oRow:cTable == ::cTable

      cDeleteQuery += AllTrim(Str(oRow:nRowID))

      if msqlQuery(::nSocket, cDeleteQuery) == 1
         return .T.
      else
         ::lError := .T.
      endif
  endif

return .F.
tmsql.prg476
TMSQLTABLE:METHODAppend(oRow) CLASS TmSQLTable
METHOD Append(oRow) CLASS TmSQLTable

   local cInsertQuery := "INSERT INTO " + ::cTable + " ("
   local i, cField

   // is this a row of this table ?
   if oRow:cTable == ::cTable

      // field names
      for i := 1 to Len(oRow:aRow)
         cInsertQuery += oRow:aFieldStruct[i][MSQL_FS_NAME] + ","
      next
      // remove last comma from list
      cInsertQuery := Left(cInsertQuery, Len(cInsertQuery) -1) + ") VALUES ("

      // field values
      for i := 1 to Len(oRow:aRow)

         do case
         case Valtype(oRow:aRow[i]) == "N"
            cField := AllTrim(Str(oRow:aRow[i]))
            cInsertQuery += cField + ","

         case Valtype(oRow:aRow[i]) == "C"
            cInsertQuery += "'" + oRow:aRow[i] + "',"

         case Valtype(oRow:aRow[i]) == "D"
            if !Empty(oRow:aRow[i])
               // mSQL dates have this form " 1-Oct-1990"
               /* NOTE: current implementation CANNOT retrieve from mSQL dates BEFORE 1st January 1970 */
               cInsertQuery += "'" + Str(Day(oRow:aRow[i]), 2) + "-" + Left(CMonth(oRow:aRow[i]), 3) + "-" + Str(Year(oRow:aRow[i]), 4) +  "',"
            else
               cInsertQuery += "'',"
            endif

        case Valtype(oRow:aRow[i]) == "L"
            cField := AllTrim(Str(iif(oRow:aRow[i] == .F., 0, 1)))
            cInsertQuery += cField + ","

         otherwise
            cInsertQuery += "'',"

         endcase
      next

      // remove last comma from list of values and add closing parenthesis
      cInsertQuery := Left(cInsertQuery, Len(cInsertQuery) -1) + ")"

      if msqlQuery(::nSocket, cInsertQuery) == 1
         return .T.
      else
         ::lError := .T.
      endif

   endif

return .F.
tmsql.prg496
TMSQLTABLE:METHODGetBlankRow() CLASS TmSQLTable
METHOD GetBlankRow() CLASS TmSQLTable

   local i
   local aRow := {}

   // crate an array of empty fields
   for i := 1 to ::FCount()
      do case
      case ::aFieldStruct[i][MSQL_FS_TYPE] == MSQL_CHAR_TYPE
         AAdd(aRow, "")

      case ::aFieldStruct[i][MSQL_FS_TYPE] == MSQL_INT_TYPE
         AAdd(aRow, 0)

      case ::aFieldStruct[i][MSQL_FS_TYPE] == MSQL_UINT_TYPE
         AAdd(aRow, .F.)

      case ::aFieldStruct[i][MSQL_FS_TYPE] == MSQL_REAL_TYPE
         AAdd(aRow, 0.0)

      case ::aFieldStruct[i][MSQL_FS_TYPE] == MSQL_DATE_TYPE
         AAdd(aRow, CToD(""))

      otherwise
         AAdd(aRow, nil)

      endcase
   next

return TmSQLRow():New(aRow, ::aFieldStruct, ::cTable, .F.)
tmsql.prg555
CLASSTmSQLServer
CLASS TmSQLServer

   DATA  nSocket                 // connection handle to server
   DATA  cServer                 // server name
   DATA  cDBName                 // Selected DB
   DATA  lError                  // .T. if occurred an error

   METHOD   New(cServer)         // Open connection to a server, returns a server object
   METHOD   Destroy()            // Closes connection to server

   METHOD   SelectDB(cDBName)    // Which data base I will use for subsequent queries

   METHOD   CreateTable(cTable, aStruct)  // Create new table using the same syntax of dbCreate()
   METHOD   DeleteTable(cTable)           // delete table
   METHOD   TableStruct(cTable)           // returns a structure array compatible with clipper's dbStruct() ones
   METHOD   CreateIndex(cName, cTable, aFNames, lUnique) // Create an index (unique) on field name(s) passed as an array of strings aFNames
   METHOD   DeleteIndex(cName, cTable)                   // Delete index cName from cTable

   METHOD   ListDBs()            // returns an array with list of data bases available
   METHOD   ListTables()         // returns an array with list of available tables in current database

   METHOD   Query(cQuery)        // Gets a textual query and returns a TmSQLQuery or TmSQLTable object
tmsql.prg590
TMSQLSERVER:METHODNetErr()
   METHOD   NetErr() INLINE ::lError         // Returns .T. if something went wrong
   METHOD   Error()                          // Returns textual description of last error

ENDCLASS
tmsql.prg613
TMSQLSERVER:METHODNew(cServer) CLASS TmSQLServer
METHOD New(cServer) CLASS TmSQLServer

   ::cServer := cServer
   ::cDBName := ""
   ::nSocket := msqlConnec(cServer)
   ::lError := .F.

   if ::nSocket == -1
      ::lError := .T.
   endif

return Self
tmsql.prg619
TMSQLSERVER:METHODSelectDB(cDBName) CLASS TmSQLServer
METHOD SelectDB(cDBName) CLASS TmSQLServer

   if msqlSelect(::nSocket, cDBName) >= 0
      ::cDBName := cDBName
      return .T.
   else
      ::cDBName := ""
   endif

return .F.
tmsql.prg633
TMSQLSERVER:METHODCreateTable(cTable, aStruct) CLASS TmSQLServer
METHOD CreateTable(cTable, aStruct) CLASS TmSQLServer

   local cCreateQuery := "CREATE TABLE " + cTable + " ("
   local i

   for i := 1 to Len(aStruct)
      do case
      case aStruct[i][DBS_TYPE] == "C"
         cCreateQuery += aStruct[i][DBS_NAME] + " char(" + AllTrim(Str(aStruct[i][DBS_LEN])) + "),"

      case aStruct[i][DBS_TYPE] == "N"
         if aStruct[i][DBS_DEC] == 0
            cCreateQuery += aStruct[i][DBS_NAME] + " int,"
         else
            cCreateQuery += aStruct[i][DBS_NAME] + " real,"
         endif

      case aStruct[i][DBS_TYPE] == "D"
         cCreateQuery += aStruct[i][DBS_NAME] + " date,"

      case aStruct[i][DBS_TYPE] == "L"
         cCreateQuery += aStruct[i][DBS_NAME] + " uint,"

      otherwise
         cCreateQuery += aStruct[i][DBS_NAME] + " char(" + AllTrim(Str(aStruct[i][DBS_LEN])) + "),"

      endcase

   next

   // remove last comma from list
   cCreateQuery := Left(cCreateQuery, Len(cCreateQuery) -1) + ")"

   if msqlQuery(::nSocket, cCreateQuery) == 1
      return .T.
   else
      ::lError := .T.
   endif

return .F.
tmsql.prg645
TMSQLSERVER:METHODCreateIndex(cName, cTable, aFNames, lUnique) CLASS TmSQLServer
METHOD CreateIndex(cName, cTable, aFNames, lUnique) CLASS TmSQLServer

   local cCreateQuery := "CREATE "
   local i

   default lUnique to .F.

   if lUnique
      cCreateQuery += "UNIQUE INDEX "
   else
      cCreateQuery += "INDEX "
   endif

   cCreateQuery += cName + " ON " + cTable + " ("

   for i := 1 to Len(aFNames)
      cCreateQuery += aFNames[i] + ","
   next

   // remove last comma from list
   cCreateQuery := Left(cCreateQuery, Len(cCreateQuery) -1) + ")"

   if msqlQuery(::nSocket, cCreateQuery) == 1
      return .T.
   endif

return .F.
tmsql.prg687
TMSQLSERVER:METHODDeleteIndex(cName, cTable) CLASS TmSQLServer
METHOD DeleteIndex(cName, cTable) CLASS TmSQLServer

   local cDropQuery := "DROP INDEX " + cName + " FROM " + cTable

   if msqlQuery(::nSocket, cDropQuery) == 1
      return .T.
   endif

return .F.
tmsql.prg716
TMSQLSERVER:METHODDeleteTable(cTable) CLASS TmSQLServer
METHOD DeleteTable(cTable) CLASS TmSQLServer

   local cDropQuery := "DROP TABLE " + cTable

   if msqlQuery(::nSocket, cDropQuery) == 1
      return .T.
   endif

return .F.
tmsql.prg727
TMSQLSERVER:METHODQuery(cQuery) CLASS TmSQLServer
METHOD Query(cQuery) CLASS TmSQLServer

   local oQuery, cTableName, i, cUpperQuery, nNumTables, cToken

   cUpperQuery := Upper(AllTrim(cQuery))
   i := 1
   nNumTables := 0

   while !( __StrToken(cUpperQuery, i++, " ") == "FROM" )
   enddo

   while !( (cToken := __StrToken(cUpperQuery, i++, " ")) == "WHERE" ) .AND. !( cToken == "LIMIT" ) .AND. !Empty(cToken)
      cTableName := __StrToken(cQuery, i - 1, " ")
      nNumTables++
   enddo

   if nNumTables == 1
      oQuery := TmSQLTable():New(::nSocket, cQuery, cTableName)
   else
      oQuery := TmSQLQuery():New(::nSocket, cQuery)
   endif

   if oQuery:nNumRows < 0
      ::lError := .T.
   endif

return oQuery
tmsql.prg738
TMSQLSERVER:METHODDestroy() CLASS TmSQLServer
METHOD Destroy() CLASS TmSQLServer

   msqlClose(::nSocket)

return Self
tmsql.prg767
TMSQLSERVER:METHODError() CLASS TmSQLServer
METHOD Error() CLASS TmSQLServer

   ::lError := .F.

return msqlGetErr()
tmsql.prg774
TMSQLSERVER:METHODListDBs() CLASS TmSQLServer
METHOD ListDBs() CLASS TmSQLServer

   local aList

   aList := msqlListDB(::nSocket)

return aList
tmsql.prg781
TMSQLSERVER:METHODListTables() CLASS TmSQLServer
METHOD ListTables() CLASS TmSQLServer

   local aList

   aList := msqlListTa(::nSocket)

return aList
tmsql.prg790
TMSQLSERVER:METHODTableStruct(cTable) CLASS TmSQLServer
METHOD TableStruct(cTable) CLASS TmSQLServer

   local nRes, aField, aStruct, aSField, i

   aStruct := {}
   nRes := msqlListFi(::nSocket, cTable)

   if !Empty( nRes )
      for i := 1 to msqlNumFie(nRes)

         aField := msqlFetchF(nRes)
         aSField := Array(DBS_DEC)

         // don't count indexes as real fields
         if aField[MSQL_FS_TYPE] <= MSQL_LAST_REAL_TYPE

            aSField[DBS_NAME] := Left(aField[MSQL_FS_NAME], 10)
            aSField[DBS_DEC] := 0

            do case
            case aField[MSQL_FS_TYPE] == MSQL_INT_TYPE
               aSField[DBS_TYPE] := "N"
               aSField[DBS_LEN] := 11

            case aField[MSQL_FS_TYPE] == MSQL_UINT_TYPE
               aSField[DBS_TYPE] := "L"
               aSField[DBS_LEN] := 1

            case aField[MSQL_FS_TYPE] == MSQL_CHAR_TYPE
               aSField[DBS_TYPE] := "C"
               aSField[DBS_LEN] := aField[MSQL_FS_LENGTH]

            case aField[MSQL_FS_TYPE] == MSQL_DATE_TYPE
               aSField[DBS_TYPE] := "D"
               aSField[DBS_LEN] := aField[MSQL_FS_LENGTH]

            case aField[MSQL_FS_TYPE] == MSQL_REAL_TYPE
               aSField[DBS_TYPE] := "N"
               aSField[DBS_LEN] := 12
               aSFIeld[DBS_DEC] := 8

            otherwise

            endcase

            AAdd(aStruct, aSField)
         endif
      next

      msqlFreeR(nRes)

   endif

return aStruct
tmsql.prg800

Page url: http://www.yourdomain.com/help/index.html?hbmsql.htm