Drizzled Public API Documentation

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