コード例 #1
0
ファイル: state.c プロジェクト: bnoordhuis/phode
drizzle_return_t drizzle_state_packet_read(drizzle_con_st *con)
{
  drizzle_log_debug(con->drizzle, "drizzle_state_packet_read");

  if (con->buffer_size < 4)
  {
    drizzle_state_push(con, drizzle_state_read);
    return DRIZZLE_RETURN_OK;
  }

  con->packet_size= drizzle_get_byte3(con->buffer_ptr);

  if (con->packet_number != con->buffer_ptr[3])
  {
    drizzle_set_error(con->drizzle, "drizzle_state_packet_read",
                      "bad packet number:%u:%u", con->packet_number,
                      con->buffer_ptr[3]);
    return DRIZZLE_RETURN_BAD_PACKET_NUMBER;
  }

  drizzle_log_debug(con->drizzle, "packet_size= %zu, packet_number= %u",
                    con->packet_size, con->packet_number);

  con->packet_number++;

  con->buffer_ptr+= 4;
  con->buffer_size-= 4;

  drizzle_state_pop(con);
  return DRIZZLE_RETURN_OK;
}
コード例 #2
0
ファイル: row.c プロジェクト: ezaze/youku
drizzle_return_t drizzle_state_row_write(drizzle_con_st *con)
{
  uint8_t *start= con->buffer_ptr + con->buffer_size;

  drizzle_log_debug(con->drizzle, "drizzle_state_row_write");

  /* Flush buffer if there is not enough room. */
  if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) < 4)
  {
    drizzle_state_push(con, drizzle_state_write);
    return DRIZZLE_RETURN_OK;
  }

  drizzle_set_byte3(start, con->packet_size);
  start[3]= con->packet_number;
  con->packet_number++;

  con->buffer_size+= 4;

  drizzle_state_pop(con);
  return DRIZZLE_RETURN_OK;
}
コード例 #3
0
ファイル: row.c プロジェクト: ezaze/youku
drizzle_return_t drizzle_state_row_read(drizzle_con_st *con)
{
  drizzle_log_debug(con->drizzle, "drizzle_state_row_read");

  if (con->packet_size != 0 && con->buffer_size < con->packet_size && 
    con->buffer_size < 5)
  {
    drizzle_state_push(con, drizzle_state_read);
    return DRIZZLE_RETURN_OK;
  }

  if (con->packet_size == 5 && con->buffer_ptr[0] == 254)
  {
    /* Got EOF packet, no more rows. */
    con->result->row_current= 0;
    con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
    con->status= drizzle_get_byte2(con->buffer_ptr + 3);
    con->buffer_ptr+= 5;
    con->buffer_size-= 5;
  }
  else if (con->buffer_ptr[0] == 255)
  {
    drizzle_state_pop(con);
    drizzle_state_push(con, drizzle_state_result_read);
    return DRIZZLE_RETURN_OK;
  }
  else if (con->result->options & DRIZZLE_RESULT_ROW_BREAK)
    con->result->options&= (drizzle_result_options_t)~DRIZZLE_RESULT_ROW_BREAK;
  else
  {
    con->result->row_count++;
    con->result->row_current++;
    con->result->field_current= 0;
  }

  drizzle_state_pop(con);
  return DRIZZLE_RETURN_OK;
}
コード例 #4
0
ファイル: field.c プロジェクト: bnoordhuis/phode
drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
{
  uint8_t *start= con->buffer_ptr + con->buffer_size;
  uint8_t *ptr;
  size_t free_size;
  drizzle_result_st *result= con->result;

  drizzle_log_debug(con->drizzle, "drizzle_state_field_write");

  if (result->field == NULL && result->field_total != 0)
    return DRIZZLE_RETURN_PAUSE;

  free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
  ptr= start;

  if (result->field_offset == 0)
  {
    /* Make sure we can fit the max length and 1 byte of data in (9 + 1). */
    if (free_size < 10)
    {
      drizzle_state_push(con, drizzle_state_write);
      return DRIZZLE_RETURN_OK;
    }

    if (result->field == NULL)
    {
      ptr[0]= 251;
      ptr++;
    }
    else if (result->field_total == 0)
    {
      ptr[0]= 0;
      ptr++;
    }
    else
      ptr= drizzle_pack_length(result->field_total, ptr);

    free_size-= (size_t)(ptr - start);
    con->buffer_size+= (size_t)(ptr - start);
    con->packet_size-= (size_t)(ptr - start);
  }
  else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
  {
    /* Flush the internal buffer first. */
    if (con->buffer_size != 0)
    {
      drizzle_state_push(con, drizzle_state_write);
      return DRIZZLE_RETURN_OK;
    }

    /* We do this to write directly from the field buffer to avoid memcpy(). */
    con->buffer_ptr= (uint8_t *)result->field;
    con->buffer_size= result->field_size;
    con->packet_size-= result->field_size;
    result->field_offset+= result->field_size;
    result->field= NULL;

    if (result->field_offset == result->field_total)
      drizzle_state_pop(con);
    else if (con->packet_size == 0)
    {
      con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
      drizzle_state_pop(con);
    }

    drizzle_state_push(con, drizzle_state_write);
    return DRIZZLE_RETURN_OK;
  }

  if (result->field_size == 0)
    drizzle_state_pop(con);
  else
  {
    if (result->field_size < free_size)
      free_size= result->field_size;

    memcpy(ptr, result->field, free_size);
    result->field_offset+= free_size;
    con->buffer_size+= free_size;
    con->packet_size-= free_size;

    if (result->field_offset == result->field_total)
    {
      result->field= NULL;
      drizzle_state_pop(con);
    }
    else
    {
      if (con->packet_size == 0)
      {
        con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
        drizzle_state_pop(con);
      }

      if (result->field_size == free_size)
        result->field= NULL;
      else
      {
        result->field+= free_size;
        result->field_size-= free_size;
        drizzle_state_push(con, drizzle_state_write);
      }
    }
  }

  return DRIZZLE_RETURN_OK;
}
コード例 #5
0
ファイル: field.c プロジェクト: bnoordhuis/phode
drizzle_return_t drizzle_state_field_read(drizzle_con_st *con)
{
  drizzle_return_t ret;

  drizzle_log_debug(con->drizzle, "drizzle_state_field_read");

  if (con->buffer_size == 0)
  {
    drizzle_state_push(con, drizzle_state_read);
    return DRIZZLE_RETURN_OK;
  }

  con->result->field_offset+= con->result->field_size;
  if (con->result->field_offset == con->result->field_total)
  {
    con->result->field_offset= 0;
    con->result->field_size= 0;

    con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
    if (ret == DRIZZLE_RETURN_NULL_SIZE)
    {
      con->result->field= NULL;
      con->result->field_current++;
      drizzle_state_pop(con);
      return DRIZZLE_RETURN_OK;
    }
    else if (ret != DRIZZLE_RETURN_OK)
    {
      if (ret == DRIZZLE_RETURN_IO_WAIT)
      {
        drizzle_state_push(con, drizzle_state_read);
        return DRIZZLE_RETURN_OK;
      }

      return ret;
    }

    drizzle_log_debug(con->drizzle,
                      "field_offset= %zu, field_size= %zu, field_total= %zu",
                      con->result->field_offset, con->result->field_size,
                      con->result->field_total);

    if ((size_t)(con->buffer_size) >= con->result->field_total)
      con->result->field_size= con->result->field_total;
    else
      con->result->field_size= con->buffer_size;
  }
  else
  {
    if ((con->result->field_offset + con->buffer_size) >=
        con->result->field_total)
    {
      con->result->field_size= (con->result->field_total -
                                con->result->field_offset);
    }
    else
      con->result->field_size= con->buffer_size;
  }

  /* This is a special case when a row is larger than the packet size. */
  if (con->result->field_size > (size_t)con->packet_size)
  {
    con->result->field_size= con->packet_size;

    if (con->options & DRIZZLE_CON_RAW_PACKET)
      con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
    else
    {
      drizzle_state_pop(con);
      drizzle_state_push(con, drizzle_state_packet_read);
      drizzle_state_push(con, drizzle_state_field_read);
    }
  }

  con->result->field= (char *)con->buffer_ptr;
  con->buffer_ptr+= con->result->field_size;
  con->buffer_size-= con->result->field_size;
  con->packet_size-= con->result->field_size;

  drizzle_log_debug(con->drizzle,
                    "field_offset= %zu, field_size= %zu, field_total= %zu",
                    con->result->field_offset, con->result->field_size,
                    con->result->field_total);

  if ((con->result->field_offset + con->result->field_size) ==
      con->result->field_total)
  {
    if (con->result->column_buffer != NULL &&
        con->result->column_buffer[con->result->field_current].max_size <
        con->result->field_total)
    {
      con->result->column_buffer[con->result->field_current].max_size=
                                                       con->result->field_total;
    }

    con->result->field_current++;
  }

  if (con->result->field_total == 0 || con->result->field_size > 0 ||
      con->packet_size == 0)
  {
    drizzle_state_pop(con);
  }

  return DRIZZLE_RETURN_OK;
}
コード例 #6
0
ファイル: result.c プロジェクト: ezaze/youku
drizzle_return_t drizzle_state_result_write(drizzle_con_st *con)
{
  uint8_t *start= con->buffer_ptr + con->buffer_size;
  uint8_t *ptr;
  drizzle_result_st *result= con->result;

  drizzle_log_debug(con->drizzle, "drizzle_state_result_write");

  /* Calculate max packet size. */
  con->packet_size= 1 /* OK/Field Count/EOF/Error */
                  + 9 /* Affected rows */
                  + 9 /* Insert ID */
                  + 2 /* Status */
                  + 2 /* Warning count */
                  + strlen(result->info); /* Info/error message */

  /* Assume the entire result packet will fit in the buffer. */
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
  {
    drizzle_set_error(con->drizzle, "drizzle_state_result_write",
                      "buffer too small:%zu", con->packet_size + 4);
    return DRIZZLE_RETURN_INTERNAL_ERROR;
  }

  /* Flush buffer if there is not enough room. */
  if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) <
      con->packet_size)
  {
    drizzle_state_push(con, drizzle_state_write);
    return DRIZZLE_RETURN_OK;
  }

  /* Store packet size at the end since it may change. */
  ptr= start;
  ptr[3]= con->packet_number;
  con->packet_number++;
  ptr+= 4;

  if (result->options & DRIZZLE_RESULT_EOF_PACKET)
  {
    ptr[0]= 254;
    ptr++;

    drizzle_set_byte2(ptr, result->warning_count);
    ptr+= 2;

    drizzle_set_byte2(ptr, con->status);
    ptr+= 2;
  }
  else if (result->error_code != 0)
  {
    ptr[0]= 255;
    ptr++;

    drizzle_set_byte2(ptr, result->error_code);
    ptr+= 2;

    ptr[0]= '#';
    ptr++;

    memcpy(ptr, result->sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE);
    ptr+= DRIZZLE_MAX_SQLSTATE_SIZE;

    memcpy(ptr, result->info, strlen(result->info));
    ptr+= strlen(result->info);
  }
  else if (result->column_count == 0)
  {
    ptr[0]= 0;
    ptr++;

    ptr= drizzle_pack_length(result->affected_rows, ptr);
    ptr= drizzle_pack_length(result->insert_id, ptr);

    drizzle_set_byte2(ptr, con->status);
    ptr+= 2;

    drizzle_set_byte2(ptr, result->warning_count);
    ptr+= 2;

    memcpy(ptr, result->info, strlen(result->info));
    ptr+= strlen(result->info);
  }
  else
    ptr= drizzle_pack_length(result->column_count, ptr);

  con->packet_size= ((size_t)(ptr - start) - 4);
  con->buffer_size+= (4 + con->packet_size);

  /* Store packet size now. */
  drizzle_set_byte3(start, con->packet_size);

  drizzle_state_pop(con);
  return DRIZZLE_RETURN_OK;
}
コード例 #7
0
ファイル: result.c プロジェクト: ezaze/youku
drizzle_return_t drizzle_state_result_read(drizzle_con_st *con)
{
  drizzle_return_t ret;

  drizzle_log_debug(con->drizzle, "drizzle_state_result_read");

  /* Assume the entire result packet will fit in the buffer. */
  if (con->buffer_size < con->packet_size)
  {
    drizzle_state_push(con, drizzle_state_read);
    return DRIZZLE_RETURN_OK;
  }

  if (con->buffer_ptr[0] == 0)
  {
    con->buffer_ptr++;
    /* We can ignore the returns since we've buffered the entire packet. */
    con->result->affected_rows= drizzle_unpack_length(con, &ret);
    con->result->insert_id= drizzle_unpack_length(con, &ret);
    con->status= drizzle_get_byte2(con->buffer_ptr);
    con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 2);
    con->buffer_ptr+= 4;
    con->buffer_size-= 5;
    con->packet_size-= 5;
    if (con->packet_size > 0)
    {
      /* Skip one byte for message size. */
      con->buffer_ptr+= 1;
      con->buffer_size-= 1;
      con->packet_size-= 1;
    }
    ret= DRIZZLE_RETURN_OK;
  }
  else if (con->buffer_ptr[0] == 254)
  {
    con->result->options= DRIZZLE_RESULT_EOF_PACKET;
    con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
    con->status= drizzle_get_byte2(con->buffer_ptr + 3);
    con->buffer_ptr+= 5;
    con->buffer_size-= 5;
    con->packet_size-= 5;
    ret= DRIZZLE_RETURN_OK;
  }
  else if (con->buffer_ptr[0] == 255)
  {
    con->result->error_code= drizzle_get_byte2(con->buffer_ptr + 1);
    con->drizzle->error_code= con->result->error_code;
    /* Byte 3 is always a '#' character, skip it. */
    memcpy(con->result->sqlstate, con->buffer_ptr + 4,
           DRIZZLE_MAX_SQLSTATE_SIZE);
    con->result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
    memcpy(con->drizzle->sqlstate, con->result->sqlstate,
           DRIZZLE_MAX_SQLSTATE_SIZE + 1);
    con->buffer_ptr+= 9;
    con->buffer_size-= 9;
    con->packet_size-= 9;
    ret= DRIZZLE_RETURN_ERROR_CODE;
  }
  else
  {
    /* We can ignore the return since we've buffered the entire packet. */
    con->result->column_count= (uint16_t)drizzle_unpack_length(con, &ret);
    ret= DRIZZLE_RETURN_OK;
  }

  if (con->packet_size > 0)
  {
    snprintf(con->drizzle->last_error, DRIZZLE_MAX_ERROR_SIZE, "%.*s",
             (int32_t)con->packet_size, con->buffer_ptr);
    con->drizzle->last_error[DRIZZLE_MAX_ERROR_SIZE-1]= 0;
    snprintf(con->result->info, DRIZZLE_MAX_INFO_SIZE, "%.*s",
             (int32_t)con->packet_size, con->buffer_ptr);
    con->result->info[DRIZZLE_MAX_INFO_SIZE-1]= 0;
    con->buffer_ptr+= con->packet_size;
    con->buffer_size-= con->packet_size;
    con->packet_size= 0;
  }

  drizzle_state_pop(con);
  return ret;
}
コード例 #8
0
ファイル: column.c プロジェクト: ezaze/youku
drizzle_return_t drizzle_state_column_write(drizzle_con_st *con)
{
  uint8_t *start= con->buffer_ptr + con->buffer_size;
  uint8_t *ptr;
  drizzle_column_st *column= con->result->column;

  drizzle_log_debug(con->drizzle, "drizzle_state_column_write");

  /* Calculate max packet size. */
  con->packet_size= 9 + strlen(column->catalog)
                  + 9 + strlen(column->db)
                  + 9 + strlen(column->table)
                  + 9 + strlen(column->orig_table)
                  + 9 + strlen(column->name)
                  + 9 + strlen(column->orig_name)
                  + 1   /* Unused */
                  + 2   /* Charset */
                  + 4   /* Size */
                  + 1   /* Type */
                  + 2   /* Flags */
                  + 1   /* Decimals */
                  + 2   /* Unused */
                  + column->default_value_size;

  /* Assume the entire column packet will fit in the buffer. */
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
  {
    drizzle_set_error(con->drizzle, "drizzle_state_column_write",
                      "buffer too small:%zu", con->packet_size + 4);
    return DRIZZLE_RETURN_INTERNAL_ERROR;
  }

  /* Flush buffer if there is not enough room. */
  if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) <
      con->packet_size)
  {
    drizzle_state_push(con, drizzle_state_write);
    return DRIZZLE_RETURN_OK;
  }

  /* Store packet size at the end since it may change. */
  ptr= start;
  ptr[3]= con->packet_number;
  con->packet_number++;
  ptr+= 4;

  ptr= drizzle_pack_string(column->catalog, ptr);
  ptr= drizzle_pack_string(column->db, ptr);
  ptr= drizzle_pack_string(column->table, ptr);
  ptr= drizzle_pack_string(column->orig_table, ptr);
  ptr= drizzle_pack_string(column->name, ptr);
  ptr= drizzle_pack_string(column->orig_name, ptr);

  /* This unused byte is set to 12 for some reason. */
  ptr[0]= 12;
  ptr++;

  drizzle_set_byte2(ptr, column->charset);
  ptr+= 2;

  drizzle_set_byte4(ptr, column->size);
  ptr+= 4;

  if (con->options & DRIZZLE_CON_MYSQL)
    ptr[0]= column->type;
  else
    ptr[0]= _column_type_drizzle_map_from[column->type];
  ptr++;

  drizzle_set_byte2(ptr, column->flags);
  ptr+= 2;

  ptr[0]= column->decimals;
  ptr++;

  memset(ptr, 0, 2);
  ptr+= 2;

  if (column->default_value_size > 0)
  {
    memcpy(ptr, column->default_value, column->default_value_size);
    ptr+= column->default_value_size;
  }

  con->packet_size= ((size_t)(ptr - start) - 4);
  con->buffer_size+= (4 + con->packet_size);

  /* Store packet size now. */
  drizzle_set_byte3(start, con->packet_size);

  con->result->column_current++;

  drizzle_state_pop(con);

  return DRIZZLE_RETURN_OK;
}
コード例 #9
0
ファイル: column.c プロジェクト: ezaze/youku
drizzle_return_t drizzle_state_column_read(drizzle_con_st *con)
{
  drizzle_column_st *column;
  drizzle_column_type_drizzle_t drizzle_type;

  drizzle_log_debug(con->drizzle, "drizzle_state_column_read");

  /* Assume the entire column packet will fit in the buffer. */
  if (con->buffer_size < con->packet_size)
  {
    drizzle_state_push(con, drizzle_state_read);
    return DRIZZLE_RETURN_OK;
  }

  if (con->packet_size == 5 && con->buffer_ptr[0] == 254)
  {
    /* EOF packet marking end of columns. */
    con->result->column= NULL;
    con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
    con->status= drizzle_get_byte2(con->buffer_ptr + 3);
    con->buffer_ptr+= 5;
    con->buffer_size-= 5;

    drizzle_state_pop(con);
  }
  else if (con->result->options & DRIZZLE_RESULT_SKIP_COLUMN)
  {
    con->buffer_ptr+= con->packet_size;
    con->buffer_size-= con->packet_size;
    con->packet_size= 0;

    drizzle_state_push(con, drizzle_state_packet_read);
  }
  else
  {
    column= drizzle_column_create(con->result, con->result->column);
    if (column == NULL)
      return DRIZZLE_RETURN_MEMORY;

    con->result->column= column;

    /* These functions can only fail if they need to read data, but we know we
       buffered the entire packet, so ignore returns. */
    (void)drizzle_unpack_string(con, column->catalog, DRIZZLE_MAX_CATALOG_SIZE);
    (void)drizzle_unpack_string(con, column->db, DRIZZLE_MAX_DB_SIZE);
    (void)drizzle_unpack_string(con, column->table, DRIZZLE_MAX_TABLE_SIZE);
    (void)drizzle_unpack_string(con, column->orig_table,
                                DRIZZLE_MAX_TABLE_SIZE);
    (void)drizzle_unpack_string(con, column->name,
                                DRIZZLE_MAX_COLUMN_NAME_SIZE);
    (void)drizzle_unpack_string(con, column->orig_name,
                                DRIZZLE_MAX_COLUMN_NAME_SIZE);

    /* Skip one filler byte. */
    column->charset= (drizzle_charset_t)drizzle_get_byte2(con->buffer_ptr + 1);
    column->size= drizzle_get_byte4(con->buffer_ptr + 3);

    if (con->options & DRIZZLE_CON_MYSQL)
      column->type= con->buffer_ptr[7];
    else
    {
      drizzle_type= con->buffer_ptr[7];
      if (drizzle_type >= DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX)
        drizzle_type= DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX;
      column->type= _column_type_drizzle_map_to[drizzle_type];
    }

    column->flags= drizzle_get_byte2(con->buffer_ptr + 8);
    if (column->type <= DRIZZLE_COLUMN_TYPE_INT24 &&
        column->type != DRIZZLE_COLUMN_TYPE_TIMESTAMP)
    {
      column->flags|= DRIZZLE_COLUMN_FLAGS_NUM;
    }

    column->decimals= con->buffer_ptr[10];
    /* Skip two reserved bytes. */

    con->buffer_ptr+= 13;
    con->buffer_size-= 13;
    con->packet_size-= 13;

    if (con->packet_size > 0)
    {
      drizzle_column_set_default_value(column, con->buffer_ptr,
                                       con->packet_size);

      con->buffer_ptr+= con->packet_size;
      con->buffer_size-= con->packet_size;
    }
    else
      column->default_value[0]= 0;

    con->result->column_current++;

    drizzle_state_pop(con);
  }

  return DRIZZLE_RETURN_OK;
}