Drizzled Public API Documentation

row.c

Go to the documentation of this file.
00001 /*
00002  * Drizzle Client & Protocol Library
00003  *
00004  * Copyright (C) 2008 Eric Day (eday@oddments.org)
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are
00009  * met:
00010  *
00011  *     * Redistributions of source code must retain the above copyright
00012  * notice, this list of conditions and the following disclaimer.
00013  *
00014  *     * Redistributions in binary form must reproduce the above
00015  * copyright notice, this list of conditions and the following disclaimer
00016  * in the documentation and/or other materials provided with the
00017  * distribution.
00018  *
00019  *     * The names of its contributors may not be used to endorse or
00020  * promote products derived from this software without specific prior
00021  * written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  */
00036 
00042 #include "common.h"
00043 
00044 /*
00045  * Client definitions
00046  */
00047 
00048 uint64_t drizzle_row_read(drizzle_result_st *result, drizzle_return_t *ret_ptr)
00049 {
00050   if (drizzle_state_none(result->con))
00051   {
00052     drizzle_state_push(result->con, drizzle_state_row_read);
00053     drizzle_state_push(result->con, drizzle_state_packet_read);
00054   }
00055 
00056   *ret_ptr= drizzle_state_loop(result->con);
00057 
00058   return result->row_current;
00059 }
00060 
00061 drizzle_row_t drizzle_row_buffer(drizzle_result_st *result,
00062                                  drizzle_return_t *ret_ptr)
00063 {
00064   size_t total;
00065   drizzle_field_t field;
00066   drizzle_row_t row;
00067 
00068   if (result->row == NULL)
00069   {
00070     if (drizzle_row_read(result, ret_ptr) == 0 || *ret_ptr != DRIZZLE_RETURN_OK)
00071       return NULL;
00072 
00073     result->row= malloc((sizeof(drizzle_field_t) + sizeof(size_t)) *
00074                         result->column_count);
00075     if (result->row == NULL)
00076     {
00077       drizzle_set_error(result->con->drizzle, "drizzle_row_buffer", "malloc");
00078       *ret_ptr= DRIZZLE_RETURN_MEMORY;
00079       return NULL;
00080     }
00081 
00082     result->field_sizes= (size_t *)(result->row + result->column_count);
00083   }
00084 
00085   while (1)
00086   {
00087     field= drizzle_field_buffer(result, &total, ret_ptr);
00088     if (*ret_ptr == DRIZZLE_RETURN_ROW_END)
00089       break;
00090     if (*ret_ptr != DRIZZLE_RETURN_OK)
00091     {
00092       if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
00093       {
00094         free(result->row);
00095         result->row= NULL;
00096         result->field_sizes= NULL;
00097       }
00098 
00099       return NULL;
00100     }
00101 
00102     result->row[result->field_current - 1]= field;
00103     result->field_sizes[result->field_current - 1]= total;
00104   }
00105 
00106   *ret_ptr= DRIZZLE_RETURN_OK;
00107   row= result->row;
00108   result->row= NULL;
00109 
00110   return row;
00111 }
00112 
00113 void drizzle_row_free(drizzle_result_st *result, drizzle_row_t row)
00114 {
00115   uint16_t x;
00116 
00117   for (x= 0; x < result->column_count; x++)
00118       drizzle_field_free(row[x]);
00119 
00120   free(row);
00121 }
00122 
00123 size_t *drizzle_row_field_sizes(drizzle_result_st *result)
00124 {
00125   return result->field_sizes;
00126 }
00127 
00128 drizzle_row_t drizzle_row_next(drizzle_result_st *result)
00129 {
00130   if (result->row_current == result->row_count)
00131     return NULL;
00132 
00133   result->field_sizes= result->field_sizes_list[result->row_current];
00134   result->row_current++;
00135   return result->row_list[result->row_current - 1];
00136 }
00137 
00138 drizzle_row_t drizzle_row_prev(drizzle_result_st *result)
00139 {
00140   if (result->row_current == 0)
00141     return NULL;
00142 
00143   result->row_current--;
00144   result->field_sizes= result->field_sizes_list[result->row_current];
00145   return result->row_list[result->row_current];
00146 }
00147 
00148 void drizzle_row_seek(drizzle_result_st *result, uint64_t row)
00149 {
00150   if (row <= result->row_count)
00151     result->row_current= row;
00152 }
00153 
00154 drizzle_row_t drizzle_row_index(drizzle_result_st *result, uint64_t row)
00155 {
00156   if (row >= result->row_count)
00157     return NULL;
00158 
00159   return result->row_list[row];
00160 }
00161 
00162 uint64_t drizzle_row_current(drizzle_result_st *result)
00163 {
00164   return result->row_current;
00165 }
00166 
00167 /*
00168  * Server definitions
00169  */
00170 
00171 drizzle_return_t drizzle_row_write(drizzle_result_st *result)
00172 {
00173   if (drizzle_state_none(result->con))
00174     drizzle_state_push(result->con, drizzle_state_row_write);
00175 
00176   return drizzle_state_loop(result->con);
00177 }
00178 
00179 /*
00180  * Internal state functions.
00181  */
00182 
00183 drizzle_return_t drizzle_state_row_read(drizzle_con_st *con)
00184 {
00185   drizzle_log_debug(con->drizzle, "drizzle_state_row_read");
00186 
00187   if (con->packet_size != 0 && con->buffer_size < con->packet_size && 
00188     con->buffer_size < 5)
00189   {
00190     drizzle_state_push(con, drizzle_state_read);
00191     return DRIZZLE_RETURN_OK;
00192   }
00193 
00194   if (con->packet_size == 5 && con->buffer_ptr[0] == 254)
00195   {
00196     /* Got EOF packet, no more rows. */
00197     con->result->row_current= 0;
00198     con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
00199     con->status= drizzle_get_byte2(con->buffer_ptr + 3);
00200     con->buffer_ptr+= 5;
00201     con->buffer_size-= 5;
00202   }
00203   else if (con->buffer_ptr[0] == 255)
00204   {
00205     drizzle_state_pop(con);
00206     drizzle_state_push(con, drizzle_state_result_read);
00207     return DRIZZLE_RETURN_OK;
00208   }
00209   else if (con->result->options & DRIZZLE_RESULT_ROW_BREAK)
00210     con->result->options&= (drizzle_result_options_t)~DRIZZLE_RESULT_ROW_BREAK;
00211   else
00212   {
00213     con->result->row_count++;
00214     con->result->row_current++;
00215     con->result->field_current= 0;
00216   }
00217 
00218   drizzle_state_pop(con);
00219   return DRIZZLE_RETURN_OK;
00220 }
00221 
00222 drizzle_return_t drizzle_state_row_write(drizzle_con_st *con)
00223 {
00224   uint8_t *start= con->buffer_ptr + con->buffer_size;
00225 
00226   drizzle_log_debug(con->drizzle, "drizzle_state_row_write");
00227 
00228   /* Flush buffer if there is not enough room. */
00229   if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) < 4)
00230   {
00231     drizzle_state_push(con, drizzle_state_write);
00232     return DRIZZLE_RETURN_OK;
00233   }
00234 
00235   drizzle_set_byte3(start, con->packet_size);
00236   start[3]= con->packet_number;
00237   con->packet_number++;
00238 
00239   con->buffer_size+= 4;
00240 
00241   drizzle_state_pop(con);
00242   return DRIZZLE_RETURN_OK;
00243 }