Blame ma_string.c

Packit Service 17f749
/************************************************************************************
Packit Service 17f749
   Copyright (C) 2013,2019 MariaDB Corporation AB
Packit Service 17f749
   
Packit Service 17f749
   This library is free software; you can redistribute it and/or
Packit Service 17f749
   modify it under the terms of the GNU Library General Public
Packit Service 17f749
   License as published by the Free Software Foundation; either
Packit Service 17f749
   version 2.1 of the License, or (at your option) any later version.
Packit Service 17f749
   
Packit Service 17f749
   This library is distributed in the hope that it will be useful,
Packit Service 17f749
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 17f749
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 17f749
   Library General Public License for more details.
Packit Service 17f749
   
Packit Service 17f749
   You should have received a copy of the GNU Library General Public
Packit Service 17f749
   License along with this library; if not see <http://www.gnu.org/licenses>
Packit Service 17f749
   or write to the Free Software Foundation, Inc., 
Packit Service 17f749
   51 Franklin St., Fifth Floor, Boston, MA 02110, USA
Packit Service 17f749
*************************************************************************************/
Packit Service 17f749
#include <ma_odbc.h>
Packit Service 17f749
Packit Service 17f749
extern MARIADB_CHARSET_INFO*  DmUnicodeCs;
Packit Service 17f749
Packit Service 17f749
char *MADB_GetTableName(MADB_Stmt *Stmt)
Packit Service 17f749
{
Packit Service 17f749
  char *TableName= NULL;
Packit Service 17f749
 unsigned  int i= 0;
Packit Service 17f749
  if (Stmt->TableName && Stmt->TableName[0])
Packit Service 17f749
    return Stmt->TableName;
Packit Service 17f749
  if (!mysql_stmt_field_count(Stmt->stmt))
Packit Service 17f749
    return NULL;
Packit Service 17f749
Packit Service 17f749
  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    if (Stmt->stmt->fields[i].org_table)
Packit Service 17f749
    {
Packit Service 17f749
      if (!TableName)
Packit Service 17f749
        TableName= Stmt->stmt->fields[i].org_table;
Packit Service 17f749
      if (strcmp(TableName, Stmt->stmt->fields[i].org_table))
Packit Service 17f749
      {
Packit Service 17f749
        MADB_SetError(&Stmt->Error, MADB_ERR_HY000, "Couldn't identify unique table name", 0);
Packit Service 17f749
        return NULL;
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  if (TableName)
Packit Service 17f749
    Stmt->TableName= _strdup(TableName);
Packit Service 17f749
  return TableName;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
char *MADB_GetCatalogName(MADB_Stmt *Stmt)
Packit Service 17f749
{
Packit Service 17f749
  char *CatalogName= NULL;
Packit Service 17f749
  unsigned int i= 0;
Packit Service 17f749
  if (Stmt->CatalogName && Stmt->CatalogName[0])
Packit Service 17f749
    return Stmt->CatalogName;
Packit Service 17f749
  if (!mysql_stmt_field_count(Stmt->stmt))
Packit Service 17f749
    return NULL;
Packit Service 17f749
Packit Service 17f749
  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    if (Stmt->stmt->fields[i].org_table)
Packit Service 17f749
    {
Packit Service 17f749
      if (!CatalogName)
Packit Service 17f749
        CatalogName= Stmt->stmt->fields[i].db;
Packit Service 17f749
      if (strcmp(CatalogName, Stmt->stmt->fields[i].db))
Packit Service 17f749
      {
Packit Service 17f749
        MADB_SetError(&Stmt->Error, MADB_ERR_HY000, "Couldn't identify unique catalog name", 0);
Packit Service 17f749
        return NULL;
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  if (CatalogName)
Packit Service 17f749
    Stmt->CatalogName= _strdup(CatalogName);
Packit Service 17f749
  return CatalogName;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynStrAppendQuoted(MADB_DynString *DynString, char *String)
Packit Service 17f749
{
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, "`") ||
Packit Service 17f749
      MADB_DynstrAppend(DynString, String) ||
Packit Service 17f749
      MADB_DynstrAppend(DynString, "`"))
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  return FALSE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynStrUpdateSet(MADB_Stmt *Stmt, MADB_DynString *DynString)
Packit Service 17f749
{
Packit Service 17f749
  int             i, IgnoredColumns= 0;
Packit Service 17f749
  MADB_DescRecord *Record;
Packit Service 17f749
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, " SET "))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
  // ???? memcpy(&Stmt->Da->Apd->Header, &Stmt->Ard->Header, sizeof(MADB_Header));
Packit Service 17f749
  for (i=0; i < MADB_STMT_COLUMN_COUNT(Stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    SQLLEN *IndicatorPtr= NULL;
Packit Service 17f749
    Record= MADB_DescGetInternalRecord(Stmt->Ard, i, MADB_DESC_READ);
Packit Service 17f749
    if (Record->IndicatorPtr)
Packit Service 17f749
      IndicatorPtr= (SQLLEN *)GetBindOffset(Stmt->Ard, Record, Record->IndicatorPtr, Stmt->DaeRowNumber > 1 ? Stmt->DaeRowNumber-1 : 0,
Packit Service 17f749
                                            sizeof(SQLLEN)/*Record->OctetLength*/);
Packit Service 17f749
    if ((IndicatorPtr && *IndicatorPtr == SQL_COLUMN_IGNORE) || !Record->inUse)
Packit Service 17f749
    {
Packit Service 17f749
      IgnoredColumns++;
Packit Service 17f749
      continue;
Packit Service 17f749
    }
Packit Service 17f749
    
Packit Service 17f749
    if ((i - IgnoredColumns) && MADB_DynstrAppend(DynString, ","))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
      return TRUE;
Packit Service 17f749
    }
Packit Service 17f749
    if (MADB_DynStrAppendQuoted(DynString, Stmt->stmt->fields[i].org_name))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
      return TRUE;
Packit Service 17f749
    }
Packit Service 17f749
    if (MADB_DynstrAppend(DynString, "=?"))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
      return TRUE;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  if (IgnoredColumns == mysql_stmt_field_count(Stmt->stmt))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_SetError(&Stmt->Error, MADB_ERR_21S02, NULL, 0);
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
  return FALSE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynStrInsertSet(MADB_Stmt *Stmt, MADB_DynString *DynString)
Packit Service 17f749
{
Packit Service 17f749
  MADB_DynString  ColVals;
Packit Service 17f749
  int             i, NeedComma= 0;
Packit Service 17f749
  MADB_DescRecord *Record;
Packit Service 17f749
Packit Service 17f749
  MADB_InitDynamicString(&ColVals, "VALUES (", 32, 32);
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, " ("))
Packit Service 17f749
  {
Packit Service 17f749
    goto dynerror;
Packit Service 17f749
    
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  /* We use only columns, that have been bound, and are not IGNORED */
Packit Service 17f749
  for (i= 0; i < MADB_STMT_COLUMN_COUNT(Stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    Record= MADB_DescGetInternalRecord(Stmt->Ard, i, MADB_DESC_READ);
Packit Service 17f749
    if (!Record->inUse || MADB_ColumnIgnoredInAllRows(Stmt->Ard, Record) == TRUE)
Packit Service 17f749
    {
Packit Service 17f749
      continue;
Packit Service 17f749
    }
Packit Service 17f749
Packit Service 17f749
    if ((NeedComma) && 
Packit Service 17f749
        (MADB_DynstrAppend(DynString, ",") || MADB_DynstrAppend(&ColVals, ",")))
Packit Service 17f749
      goto dynerror;
Packit Service 17f749
Packit Service 17f749
    if (MADB_DynStrAppendQuoted(DynString, Stmt->stmt->fields[i].org_name) ||
Packit Service 17f749
        MADB_DynstrAppend(&ColVals, "?"))
Packit Service 17f749
       goto dynerror;
Packit Service 17f749
Packit Service 17f749
    NeedComma= 1;
Packit Service 17f749
  }
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, ") " ) ||
Packit Service 17f749
      MADB_DynstrAppend(&ColVals, ")") ||
Packit Service 17f749
      MADB_DynstrAppend(DynString, ColVals.str))
Packit Service 17f749
    goto dynerror;
Packit Service 17f749
  MADB_DynstrFree(&ColVals);
Packit Service 17f749
  return FALSE;
Packit Service 17f749
dynerror:
Packit Service 17f749
  MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
  MADB_DynstrFree(&ColVals);
Packit Service 17f749
  return TRUE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynStrGetColumns(MADB_Stmt *Stmt, MADB_DynString *DynString)
Packit Service 17f749
{
Packit Service 17f749
  unsigned int i;
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, " ("))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    if (i && MADB_DynstrAppend(DynString, ", "))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
      return TRUE;
Packit Service 17f749
    }
Packit Service 17f749
    if (MADB_DynStrAppendQuoted(DynString, Stmt->stmt->fields[i].org_name))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
      return TRUE;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, " )"))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
  return FALSE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynStrGetWhere(MADB_Stmt *Stmt, MADB_DynString *DynString, char *TableName, my_bool ParameterMarkers)
Packit Service 17f749
{
Packit Service 17f749
  int UniqueCount=0, PrimaryCount= 0;
Packit Service 17f749
  int i, Flag= 0;
Packit Service 17f749
  char *Column= NULL, *Escaped= NULL;
Packit Service 17f749
  SQLLEN StrLength;
Packit Service 17f749
  unsigned long EscapedLength;
Packit Service 17f749
Packit Service 17f749
  for (i= 0; i < MADB_STMT_COLUMN_COUNT(Stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    MYSQL_FIELD *field= mysql_fetch_field_direct(FetchMetadata(Stmt), i);
Packit Service 17f749
    if (field->flags & PRI_KEY_FLAG)
Packit Service 17f749
      PrimaryCount++;
Packit Service 17f749
    if (field->flags & UNIQUE_KEY_FLAG)
Packit Service 17f749
      UniqueCount++;
Packit Service 17f749
  }
Packit Service 17f749
  /* We need to use all columns, otherwise it will be difficult to map fields for Positioned Update */
Packit Service 17f749
  if (PrimaryCount && PrimaryCount != MADB_KeyTypeCount(Stmt->Connection, TableName, PRI_KEY_FLAG))
Packit Service 17f749
    PrimaryCount= 0;
Packit Service 17f749
  if (UniqueCount && UniqueCount != MADB_KeyTypeCount(Stmt->Connection, TableName, UNIQUE_KEY_FLAG))
Packit Service 17f749
    UniqueCount= 0;
Packit Service 17f749
  
Packit Service 17f749
  /* if no primary or unique key is in the cursor, the cursor must contain all
Packit Service 17f749
     columns from table in TableName */
Packit Service 17f749
  if (!PrimaryCount && !UniqueCount)
Packit Service 17f749
  {
Packit Service 17f749
    char      StmtStr[256];
Packit Service 17f749
    MADB_Stmt *CountStmt;
Packit Service 17f749
    int       FieldCount= 0;
Packit Service 17f749
Packit Service 17f749
    MA_SQLAllocHandle(SQL_HANDLE_STMT, Stmt->Connection, (SQLHANDLE*)&CountStmt);
Packit Service 17f749
    _snprintf(StmtStr, 256, "SELECT * FROM `%s` LIMIT 0", TableName);
Packit Service 17f749
    CountStmt->Methods->ExecDirect(CountStmt, (char *)StmtStr, SQL_NTS);
Packit Service 17f749
    FieldCount= mysql_stmt_field_count(((MADB_Stmt *)CountStmt)->stmt);
Packit Service 17f749
    CountStmt->Methods->StmtFree(CountStmt, SQL_DROP);
Packit Service 17f749
Packit Service 17f749
    if (FieldCount != MADB_STMT_COLUMN_COUNT(Stmt))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetError(&Stmt->Error, MADB_ERR_S1000, "Can't build index for update/delete", 0);
Packit Service 17f749
      return TRUE;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, " WHERE 1"))
Packit Service 17f749
    goto memerror;
Packit Service 17f749
  for (i= 0; i < MADB_STMT_COLUMN_COUNT(Stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    MYSQL_FIELD *field= mysql_fetch_field_direct(Stmt->metadata, i);
Packit Service 17f749
    if (field->flags & Flag || !Flag)
Packit Service 17f749
    {
Packit Service 17f749
      if (MADB_DynstrAppend(DynString, " AND ") ||
Packit Service 17f749
          MADB_DynStrAppendQuoted(DynString, field->org_name))
Packit Service 17f749
          goto memerror;
Packit Service 17f749
      if (ParameterMarkers)
Packit Service 17f749
      {
Packit Service 17f749
        if (MADB_DynstrAppend(DynString, "=?"))
Packit Service 17f749
          goto memerror;
Packit Service 17f749
      }
Packit Service 17f749
      else
Packit Service 17f749
      { 
Packit Service 17f749
        if (!SQL_SUCCEEDED(Stmt->Methods->GetData(Stmt, i+1, SQL_C_CHAR, NULL, 0, &StrLength, TRUE)))
Packit Service 17f749
        {
Packit Service 17f749
          MADB_FREE(Column);
Packit Service 17f749
          return TRUE;
Packit Service 17f749
        }
Packit Service 17f749
        if (StrLength < 0)
Packit Service 17f749
        {
Packit Service 17f749
           if (MADB_DynstrAppend(DynString, " IS NULL"))
Packit Service 17f749
             goto memerror;
Packit Service 17f749
        }
Packit Service 17f749
        else
Packit Service 17f749
        {
Packit Service 17f749
          Column= MADB_CALLOC(StrLength + 1);
Packit Service 17f749
          Stmt->Methods->GetData(Stmt,i+1, SQL_C_CHAR, Column, StrLength + 1, &StrLength, TRUE);
Packit Service 17f749
          Escaped = MADB_CALLOC(2 * StrLength + 1);
Packit Service 17f749
          EscapedLength= mysql_real_escape_string(Stmt->Connection->mariadb, Escaped, Column, (unsigned long)StrLength);
Packit Service 17f749
Packit Service 17f749
          if (MADB_DynstrAppend(DynString, "= '") ||
Packit Service 17f749
            MADB_DynstrAppend(DynString, Escaped) ||//, EscapedLength) ||
Packit Service 17f749
            MADB_DynstrAppend(DynString, "'"))
Packit Service 17f749
          {
Packit Service 17f749
            goto memerror;
Packit Service 17f749
          }
Packit Service 17f749
          MADB_FREE(Column);
Packit Service 17f749
          MADB_FREE(Escaped);
Packit Service 17f749
        }
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, " LIMIT 1"))
Packit Service 17f749
    goto memerror;
Packit Service 17f749
  MADB_FREE(Column);
Packit Service 17f749
Packit Service 17f749
  return FALSE;
Packit Service 17f749
Packit Service 17f749
memerror:
Packit Service 17f749
  MADB_FREE(Column);
Packit Service 17f749
  MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
Packit Service 17f749
  return TRUE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynStrGetValues(MADB_Stmt *Stmt, MADB_DynString *DynString)
Packit Service 17f749
{
Packit Service 17f749
  unsigned int i;
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, " VALUES("))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    if (MADB_DynstrAppend(DynString, (i) ? ",?" : "?"))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
      return TRUE;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  if (MADB_DynstrAppend(DynString, ")"))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
Packit Service 17f749
    return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
  return FALSE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
char *MADB_GetInsertStatement(MADB_Stmt *Stmt)
Packit Service 17f749
{
Packit Service 17f749
  char *StmtStr;
Packit Service 17f749
  size_t Length= 1024;
Packit Service 17f749
  char *p;
Packit Service 17f749
  char *TableName;
Packit Service 17f749
  unsigned int i;
Packit Service 17f749
Packit Service 17f749
  if (!(StmtStr= MADB_CALLOC(1024)))
Packit Service 17f749
  {
Packit Service 17f749
    MADB_SetError(&Stmt->Error, MADB_ERR_HY013, NULL, 0);
Packit Service 17f749
    return NULL;
Packit Service 17f749
  }
Packit Service 17f749
  if (!(TableName= MADB_GetTableName(Stmt)))
Packit Service 17f749
    goto error;
Packit Service 17f749
  p= StmtStr;
Packit Service 17f749
  
Packit Service 17f749
  p+= _snprintf(StmtStr, 1024, "INSERT INTO `%s` (", TableName);
Packit Service 17f749
  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    if (strlen(StmtStr) > Length - NAME_LEN - 4/* comma + 2 ticks + terminating NULL */)
Packit Service 17f749
    {
Packit Service 17f749
      Length+= 1024;
Packit Service 17f749
      if (!(StmtStr= MADB_REALLOC(StmtStr, Length)))
Packit Service 17f749
      {
Packit Service 17f749
        MADB_SetError(&Stmt->Error, MADB_ERR_HY013, NULL, 0);
Packit Service 17f749
        goto error;
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
    p+= _snprintf(p, Length - strlen(StmtStr), "%s`%s`", (i==0) ? "" : ",", Stmt->stmt->fields[i].org_name);
Packit Service 17f749
  }
Packit Service 17f749
  p+= _snprintf(p, Length - strlen(StmtStr), ") VALUES (");
Packit Service 17f749
Packit Service 17f749
  if (strlen(StmtStr) > Length - mysql_stmt_field_count(Stmt->stmt)*2 - 1)/* , and ? for each column  + (- 1 comma for 1st column + closing ')')
Packit Service 17f749
                                                                            + terminating NULL */
Packit Service 17f749
  {
Packit Service 17f749
    Length= strlen(StmtStr) + mysql_stmt_field_count(Stmt->stmt)*2 + 1;
Packit Service 17f749
    if (!(StmtStr= MADB_REALLOC(StmtStr, Length)))
Packit Service 17f749
    {
Packit Service 17f749
      MADB_SetError(&Stmt->Error, MADB_ERR_HY013, NULL, 0);
Packit Service 17f749
      goto error;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
Packit Service 17f749
  {
Packit Service 17f749
    p+= _snprintf(p, Length - strlen(StmtStr), "%s?", (i==0) ? "" : ",");
Packit Service 17f749
  }
Packit Service 17f749
  p+= _snprintf(p, Length - strlen(StmtStr), ")");
Packit Service 17f749
  return StmtStr;
Packit Service 17f749
Packit Service 17f749
error:
Packit Service 17f749
  if (StmtStr)
Packit Service 17f749
    MADB_FREE(StmtStr);
Packit Service 17f749
  return NULL;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
my_bool MADB_ValidateStmt(MADB_QUERY *Query)
Packit Service 17f749
{
Packit Service 17f749
  return Query->QueryType != MADB_QUERY_SET_NAMES;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
char *MADB_ToLower(const char *src, char *buff, size_t buff_size)
Packit Service 17f749
{
Packit Service 17f749
  size_t i= 0;
Packit Service 17f749
Packit Service 17f749
  if (buff_size > 0)
Packit Service 17f749
  {
Packit Service 17f749
    while (*src && i < buff_size)
Packit Service 17f749
    {
Packit Service 17f749
      buff[i++]= tolower(*src++);
Packit Service 17f749
    }
Packit Service 17f749
Packit Service 17f749
    buff[i == buff_size ? i - 1 : i]= '\0';
Packit Service 17f749
  }
Packit Service 17f749
  return buff;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
int InitClientCharset(Client_Charset *cc, const char * name)
Packit Service 17f749
{
Packit Service 17f749
  /* There is no legal charset names longer than 31 chars */
Packit Service 17f749
  char lowered[32];
Packit Service 17f749
  cc->cs_info= mariadb_get_charset_by_name(MADB_ToLower(name, lowered, sizeof(lowered)));
Packit Service 17f749
Packit Service 17f749
  if (cc->cs_info == NULL)
Packit Service 17f749
  {
Packit Service 17f749
    return 1;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  cc->CodePage= cc->cs_info->codepage;
Packit Service 17f749
Packit Service 17f749
  return 0;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void CopyClientCharset(Client_Charset * Src, Client_Charset * Dst)
Packit Service 17f749
{
Packit Service 17f749
  Dst->CodePage= Src->CodePage;
Packit Service 17f749
  Dst->cs_info= Src->cs_info;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void CloseClientCharset(Client_Charset *cc)
Packit Service 17f749
{
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/* Hmmm... Length in characters is SQLLEN, octet length SQLINTEGER */
Packit Service 17f749
SQLLEN MbstrOctetLen(const char *str, SQLLEN *CharLen, MARIADB_CHARSET_INFO *cs)
Packit Service 17f749
{
Packit Service 17f749
  SQLLEN result= 0, inChars= *CharLen;
Packit Service 17f749
Packit Service 17f749
  if (str)
Packit Service 17f749
  {
Packit Service 17f749
    if (cs->mb_charlen == NULL)
Packit Service 17f749
    {
Packit Service 17f749
      /* Charset uses no more than a byte per char. Result is strlen or umber of chars */
Packit Service 17f749
      if (*CharLen < 0)
Packit Service 17f749
      {
Packit Service 17f749
        result= (SQLLEN)strlen(str);
Packit Service 17f749
        *CharLen= result;
Packit Service 17f749
      }
Packit Service 17f749
      else
Packit Service 17f749
      {
Packit Service 17f749
        result= *CharLen;
Packit Service 17f749
      }
Packit Service 17f749
      return result;
Packit Service 17f749
    }
Packit Service 17f749
    else
Packit Service 17f749
    {
Packit Service 17f749
      while (inChars > 0 || (inChars < 0 && *str))
Packit Service 17f749
      {
Packit Service 17f749
        result+= cs->mb_charlen(0 + *str);
Packit Service 17f749
        --inChars;
Packit Service 17f749
        str+= cs->mb_charlen(*str);
Packit Service 17f749
      }
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  if (*CharLen < 0)
Packit Service 17f749
  {
Packit Service 17f749
    *CharLen-= inChars;
Packit Service 17f749
  }
Packit Service 17f749
  return result;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/* Number of characters in given number of bytes */
Packit Service 17f749
SQLLEN MbstrCharLen(const char *str, SQLINTEGER OctetLen, MARIADB_CHARSET_INFO *cs)
Packit Service 17f749
{
Packit Service 17f749
  SQLLEN       result= 0;
Packit Service 17f749
  const char   *ptr= str;
Packit Service 17f749
  unsigned int charlen;
Packit Service 17f749
Packit Service 17f749
  if (str)
Packit Service 17f749
  {
Packit Service 17f749
    if (cs->mb_charlen == NULL || cs->char_maxlen == 1)
Packit Service 17f749
    {
Packit Service 17f749
      return OctetLen;
Packit Service 17f749
    }
Packit Service 17f749
    while (ptr < str + OctetLen)
Packit Service 17f749
    {
Packit Service 17f749
      charlen= cs->mb_charlen((unsigned char)*ptr);
Packit Service 17f749
      if (charlen == 0)
Packit Service 17f749
      {
Packit Service 17f749
        /* Dirty hack to avoid dead loop - Has to be the error! */
Packit Service 17f749
        charlen= 1;
Packit Service 17f749
      }
Packit Service 17f749
Packit Service 17f749
      /* Skipping thru 0 bytes */
Packit Service 17f749
      while (charlen > 0 && *ptr == '\0')
Packit Service 17f749
      {
Packit Service 17f749
          --charlen;
Packit Service 17f749
          ++ptr;
Packit Service 17f749
      }
Packit Service 17f749
Packit Service 17f749
      /* Stopping if current character is terminating NULL - charlen == 0 means all bytes of current char was 0 */
Packit Service 17f749
      if (charlen == 0)
Packit Service 17f749
      {
Packit Service 17f749
        return result;
Packit Service 17f749
      }
Packit Service 17f749
      /* else we increment ptr for number of left bytes */
Packit Service 17f749
      ptr+= charlen;
Packit Service 17f749
      ++result;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  return result;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/* Length of NT SQLWCHAR string in characters */
Packit Service 17f749
SQLINTEGER SqlwcsCharLen(SQLWCHAR *str, SQLLEN octets)
Packit Service 17f749
{
Packit Service 17f749
  SQLINTEGER result= 0;
Packit Service 17f749
  SQLWCHAR   *end=   octets != (SQLLEN)-1 ? str + octets/sizeof(SQLWCHAR) : (SQLWCHAR*)octets /*for simplicity - the address to be always bigger */;
Packit Service 17f749
Packit Service 17f749
  if (str)
Packit Service 17f749
  {
Packit Service 17f749
    while (str < end && *str)
Packit Service 17f749
    {
Packit Service 17f749
      str+= (DmUnicodeCs->mb_charlen(*str))/sizeof(SQLWCHAR);
Packit Service 17f749
Packit Service 17f749
      if (str > end)
Packit Service 17f749
      {
Packit Service 17f749
        break;
Packit Service 17f749
      }
Packit Service 17f749
      ++result;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  return result;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/* Length in SQLWCHAR units
Packit Service 17f749
   @buff_length[in] - size of the str buffer or negative number  */
Packit Service 17f749
SQLLEN SqlwcsLen(SQLWCHAR *str, SQLLEN buff_length)
Packit Service 17f749
{
Packit Service 17f749
  SQLINTEGER result= 0;
Packit Service 17f749
Packit Service 17f749
  if (str)
Packit Service 17f749
  {
Packit Service 17f749
    /* If buff_length is negative - we will never hit 1st condition, otherwise we hit it after last character
Packit Service 17f749
       of the buffer is processed */
Packit Service 17f749
    while ((--buff_length) != -1 && *str)
Packit Service 17f749
    {
Packit Service 17f749
      ++result;
Packit Service 17f749
      ++str;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  return result;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
/* Length of a string with respect to specified buffer size
Packit Service 17f749
@buff_length[in] - size of the str buffer or negative number  */
Packit Service 17f749
SQLLEN SafeStrlen(SQLCHAR *str, SQLLEN buff_length)
Packit Service 17f749
{
Packit Service 17f749
  SQLINTEGER result= 0;
Packit Service 17f749
Packit Service 17f749
  if (str)
Packit Service 17f749
  {
Packit Service 17f749
    /* If buff_length is negative - we will never hit 1st condition, otherwise we hit it after last character
Packit Service 17f749
    of the buffer is processed */
Packit Service 17f749
    while ((--buff_length) != -1 && *str)
Packit Service 17f749
    {
Packit Service 17f749
      ++result;
Packit Service 17f749
      ++str;
Packit Service 17f749
    }
Packit Service 17f749
  }
Packit Service 17f749
  return result;
Packit Service 17f749
}