Drizzled Public API Documentation

mi_rprev.cc

00001 /* Copyright (C) 2000-2001, 2004 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 #include "myisam_priv.h"
00017 
00018   /*
00019      Read previous row with the same key as previous read
00020      One may have done a write, update or delete of the previous row.
00021      NOTE! Even if one changes the previous row, the next read is done
00022      based on the position of the last used key!
00023   */
00024 
00025 int mi_rprev(MI_INFO *info, unsigned char *buf, int inx)
00026 {
00027   int error,changed;
00028   register uint32_t flag;
00029   MYISAM_SHARE *share=info->s;
00030 
00031   if ((inx = _mi_check_index(info,inx)) < 0)
00032     return(errno);
00033   flag=SEARCH_SMALLER;        /* Read previous */
00034   if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_NEXT_FOUND)
00035     flag=0;         /* Read last */
00036 
00037   if (fast_mi_readinfo(info))
00038     return(errno);
00039   changed=_mi_test_if_changed(info);
00040   if (!flag)
00041     error=_mi_search_last(info, share->keyinfo+inx,
00042         share->state.key_root[inx]);
00043   else if (!changed)
00044     error=_mi_search_next(info,share->keyinfo+inx,info->lastkey,
00045         info->lastkey_length,flag,
00046         share->state.key_root[inx]);
00047   else
00048     error=_mi_search(info,share->keyinfo+inx,info->lastkey,
00049          USE_WHOLE_KEY, flag, share->state.key_root[inx]);
00050 
00051   if (share->concurrent_insert)
00052   {
00053     if (!error)
00054     {
00055       while (info->lastpos >= info->state->data_file_length)
00056       {
00057   /* Skip rows that are inserted by other threads since we got a lock */
00058   if  ((error=_mi_search_next(info,share->keyinfo+inx,info->lastkey,
00059             info->lastkey_length,
00060             SEARCH_SMALLER,
00061             share->state.key_root[inx])))
00062     break;
00063       }
00064     }
00065   }
00066   info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
00067   info->update|= HA_STATE_PREV_FOUND;
00068   if (error)
00069   {
00070     if (errno ==  drizzled::HA_ERR_KEY_NOT_FOUND)
00071       errno= drizzled::HA_ERR_END_OF_FILE;
00072   }
00073   else if (!buf)
00074   {
00075     return(info->lastpos==HA_OFFSET_ERROR ? errno : 0);
00076   }
00077   else if (!(*info->read_record)(info,info->lastpos,buf))
00078   {
00079     info->update|= HA_STATE_AKTIV;    /* Record is read */
00080     return(0);
00081   }
00082   return(errno);
00083 } /* mi_rprev */