drizzle_query_st *drizzle_query_create(drizzle_st *drizzle, drizzle_query_st *query) { if (query == NULL) { query= malloc(sizeof(drizzle_query_st)); if (query == NULL) { drizzle_set_error(drizzle, "drizzle_query_create", "malloc"); return NULL; } memset(query, 0, sizeof(drizzle_query_st)); query->options|= DRIZZLE_CON_ALLOCATED; } else memset(query, 0, sizeof(drizzle_query_st)); query->drizzle= drizzle; if (drizzle->query_list) drizzle->query_list->prev= query; query->next= drizzle->query_list; drizzle->query_list= query; drizzle->query_count++; drizzle->query_new++; return query; }
drizzle_result_st *drizzle_result_create(drizzle_con_st *con, drizzle_result_st *result) { if (result == NULL) { result= malloc(sizeof(drizzle_result_st)); if (result == NULL) { drizzle_set_error(con->drizzle, "drizzle_result_create", "malloc"); return NULL; } memset(result, 0, sizeof(drizzle_result_st)); result->options|= DRIZZLE_RESULT_ALLOCATED; } else memset(result, 0, sizeof(drizzle_result_st)); result->con= con; con->result= result; if (con->result_list) con->result_list->prev= result; result->next= con->result_list; con->result_list= result; con->result_count++; return result; }
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; }
drizzle_return_t drizzle_column_buffer(drizzle_result_st *result) { drizzle_return_t ret; if (result->column_buffer == NULL) { if (result->column_count == 0) { result->options|= DRIZZLE_RESULT_BUFFER_COLUMN; return DRIZZLE_RETURN_OK; } result->column_buffer= malloc(sizeof(drizzle_column_st) * result->column_count); if (result->column_buffer == NULL) { drizzle_set_error(result->con->drizzle, "drizzle_column_buffer", "malloc"); return DRIZZLE_RETURN_MEMORY; } } /* No while body, just keep calling to buffer columns. */ while (drizzle_column_read(result, &(result->column_buffer[result->column_current]), &ret) != NULL && ret == DRIZZLE_RETURN_OK); if (ret == DRIZZLE_RETURN_OK) { result->column_current= 0; result->options|= DRIZZLE_RESULT_BUFFER_COLUMN; } return ret; }
drizzle_row_t drizzle_row_buffer(drizzle_result_st *result, drizzle_return_t *ret_ptr) { size_t total; drizzle_field_t field; drizzle_row_t row; if (result->row == NULL) { if (drizzle_row_read(result, ret_ptr) == 0 || *ret_ptr != DRIZZLE_RETURN_OK) return NULL; result->row= malloc((sizeof(drizzle_field_t) + sizeof(size_t)) * result->column_count); if (result->row == NULL) { drizzle_set_error(result->con->drizzle, "drizzle_row_buffer", "malloc"); *ret_ptr= DRIZZLE_RETURN_MEMORY; return NULL; } result->field_sizes= (size_t *)(result->row + result->column_count); } while (1) { field= drizzle_field_buffer(result, &total, ret_ptr); if (*ret_ptr == DRIZZLE_RETURN_ROW_END) break; if (*ret_ptr != DRIZZLE_RETURN_OK) { if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT) { free(result->row); result->row= NULL; result->field_sizes= NULL; } return NULL; } result->row[result->field_current - 1]= field; result->field_sizes[result->field_current - 1]= total; } *ret_ptr= DRIZZLE_RETURN_OK; row= result->row; result->row= NULL; return row; }
drizzle_field_t drizzle_field_buffer(drizzle_result_st *result, size_t *total, drizzle_return_t *ret_ptr) { drizzle_field_t field; size_t offset= 0; size_t size= 0; field= drizzle_field_read(result, &offset, &size, total, ret_ptr); if (*ret_ptr != DRIZZLE_RETURN_OK) return NULL; if (field == NULL) { *total= 0; return NULL; } if (result->field_buffer == NULL) { result->field_buffer= malloc((*total) + 1); if (result->field_buffer == NULL) { drizzle_set_error(result->con->drizzle, "drizzle_field_buffer", "malloc"); *ret_ptr= DRIZZLE_RETURN_MEMORY; return NULL; } } memcpy(result->field_buffer + offset, field, size); while ((offset + size) != (*total)) { field= drizzle_field_read(result, &offset, &size, total, ret_ptr); if (*ret_ptr != DRIZZLE_RETURN_OK) return NULL; memcpy(result->field_buffer + offset, field, size); } field= result->field_buffer; result->field_buffer= NULL; field[*total]= 0; return field; }
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; }
drizzle_return_t drizzle_result_buffer(drizzle_result_st *result) { drizzle_return_t ret; drizzle_row_t row; drizzle_row_t *row_list; size_t **field_sizes_list; if (!(result->options & DRIZZLE_RESULT_BUFFER_COLUMN)) { ret= drizzle_column_buffer(result); if (ret != DRIZZLE_RETURN_OK) return ret; } if (result->column_count == 0) { result->options|= DRIZZLE_RESULT_BUFFER_ROW; return DRIZZLE_RETURN_OK; } while (1) { row= drizzle_row_buffer(result, &ret); if (ret != DRIZZLE_RETURN_OK) return ret; if (row == NULL) break; if (result->row_list_size < result->row_count) { row_list= realloc(result->row_list, sizeof(drizzle_row_t) * ((size_t)(result->row_list_size) + DRIZZLE_ROW_GROW_SIZE)); if (row_list == NULL) { drizzle_row_free(result, row); drizzle_set_error(result->con->drizzle, "drizzle_result_buffer", "realloc"); return DRIZZLE_RETURN_MEMORY; } result->row_list= row_list; field_sizes_list= realloc(result->field_sizes_list, sizeof(size_t *) * ((size_t)(result->row_list_size) + DRIZZLE_ROW_GROW_SIZE)); if (field_sizes_list == NULL) { drizzle_row_free(result, row); drizzle_set_error(result->con->drizzle, "drizzle_result_buffer", "realloc"); return DRIZZLE_RETURN_MEMORY; } result->field_sizes_list= field_sizes_list; result->row_list_size+= DRIZZLE_ROW_GROW_SIZE; } result->row_list[result->row_current - 1]= row; result->field_sizes_list[result->row_current - 1]= result->field_sizes; } result->options|= DRIZZLE_RESULT_BUFFER_ROW; return DRIZZLE_RETURN_OK; }
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; }
drizzle_column_st *drizzle_column_create(drizzle_result_st *result, drizzle_column_st *column) { if (column == NULL) { column= malloc(sizeof(drizzle_column_st)); if (column == NULL) { drizzle_set_error(result->con->drizzle, "drizzle_column_create", "malloc"); return NULL; } column->result = result; /* SET BELOW: column->next */ column->prev = NULL; column->options= DRIZZLE_COLUMN_ALLOCATED; column->catalog[0] = '\0'; column->db[0] = '\0'; column->table[0] = '\0'; column->orig_table[0] = '\0'; column->name[0] = '\0'; column->orig_name[0] = '\0'; column->charset = 0; column->size = 0; column->max_size = 0; column->type = 0; column->flags = 0; column->decimals = 0; /* UNSET: column->default_value */ column->default_value_size = 0; } else { column->result = result; /* SET BELOW: column->next */ column->prev = NULL; column->options= 0; column->catalog[0] = '\0'; column->db[0] = '\0'; column->table[0] = '\0'; column->orig_table[0] = '\0'; column->name[0] = '\0'; column->orig_name[0] = '\0'; column->charset = 0; column->size = 0; column->max_size = 0; column->type = 0; column->flags = 0; column->decimals = 0; /* UNSET: column->default_value */ column->default_value_size = 0; } column->result= result; if (result->column_list) result->column_list->prev= column; column->next= result->column_list; result->column_list= column; return column; }