00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "myisam_priv.h"
00019
00020 using namespace drizzled;
00021
00022 int _mi_write_static_record(MI_INFO *info, const unsigned char *record)
00023 {
00024 unsigned char temp[8];
00025 if (info->s->state.dellink != HA_OFFSET_ERROR &&
00026 !info->append_insert_at_end)
00027 {
00028 internal::my_off_t filepos=info->s->state.dellink;
00029 info->rec_cache.seek_not_done=1;
00030 if (info->s->file_read(info, &temp[0],info->s->base.rec_reflength,
00031 info->s->state.dellink+1,
00032 MYF(MY_NABP)))
00033 goto err;
00034 info->s->state.dellink= _mi_rec_pos(info->s,temp);
00035 info->state->del--;
00036 info->state->empty-=info->s->base.pack_reclength;
00037 if (info->s->file_write(info, record, info->s->base.reclength,
00038 filepos,
00039 MYF(MY_NABP)))
00040 goto err;
00041 }
00042 else
00043 {
00044 if (info->state->data_file_length > info->s->base.max_data_file_length-
00045 info->s->base.pack_reclength)
00046 {
00047 errno=HA_ERR_RECORD_FILE_FULL;
00048 return(2);
00049 }
00050 if (info->opt_flag & WRITE_CACHE_USED)
00051 {
00052 if (my_b_write(&info->rec_cache, record,
00053 info->s->base.reclength))
00054 goto err;
00055 if (info->s->base.pack_reclength != info->s->base.reclength)
00056 {
00057 uint32_t length=info->s->base.pack_reclength - info->s->base.reclength;
00058 memset(temp, 0, length);
00059 if (my_b_write(&info->rec_cache, temp,length))
00060 goto err;
00061 }
00062 }
00063 else
00064 {
00065 info->rec_cache.seek_not_done=1;
00066 if (info->s->file_write(info, record, info->s->base.reclength,
00067 info->state->data_file_length,
00068 info->s->write_flag))
00069 goto err;
00070 if (info->s->base.pack_reclength != info->s->base.reclength)
00071 {
00072 uint32_t length=info->s->base.pack_reclength - info->s->base.reclength;
00073 memset(temp, 0, length);
00074 if (info->s->file_write(info, temp,length,
00075 info->state->data_file_length+
00076 info->s->base.reclength,
00077 info->s->write_flag))
00078 goto err;
00079 }
00080 }
00081 info->state->data_file_length+=info->s->base.pack_reclength;
00082 info->s->state.split++;
00083 }
00084 return 0;
00085 err:
00086 return 1;
00087 }
00088
00089 int _mi_update_static_record(MI_INFO *info, internal::my_off_t pos, const unsigned char *record)
00090 {
00091 info->rec_cache.seek_not_done=1;
00092 return (info->s->file_write(info,
00093 record, info->s->base.reclength,
00094 pos,
00095 MYF(MY_NABP)) != 0);
00096 }
00097
00098
00099 int _mi_delete_static_record(MI_INFO *info)
00100 {
00101 unsigned char temp[9];
00102
00103 info->state->del++;
00104 info->state->empty+=info->s->base.pack_reclength;
00105 temp[0]= '\0';
00106 _mi_dpointer(info,temp+1,info->s->state.dellink);
00107 info->s->state.dellink = info->lastpos;
00108 info->rec_cache.seek_not_done=1;
00109 return (info->s->file_write(info,(unsigned char*) temp, 1+info->s->rec_reflength,
00110 info->lastpos, MYF(MY_NABP)) != 0);
00111 }
00112
00113
00114 int _mi_cmp_static_record(register MI_INFO *info, register const unsigned char *old)
00115 {
00116 if (info->opt_flag & WRITE_CACHE_USED)
00117 {
00118 if (flush_io_cache(&info->rec_cache))
00119 {
00120 return(-1);
00121 }
00122 info->rec_cache.seek_not_done=1;
00123 }
00124
00125 if ((info->opt_flag & READ_CHECK_USED))
00126 {
00127 info->rec_cache.seek_not_done=1;
00128 if (info->s->file_read(info, info->rec_buff, info->s->base.reclength,
00129 info->lastpos,
00130 MYF(MY_NABP)))
00131 return(-1);
00132 if (memcmp(info->rec_buff, old,
00133 (uint) info->s->base.reclength))
00134 {
00135 errno=HA_ERR_RECORD_CHANGED;
00136 return(1);
00137 }
00138 }
00139 return(0);
00140 }
00141
00142
00143 int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def,
00144 const unsigned char *record, internal::my_off_t pos)
00145 {
00146 info->rec_cache.seek_not_done=1;
00147 if (info->s->file_read(info, info->rec_buff, info->s->base.reclength,
00148 pos, MYF(MY_NABP)))
00149 return(-1);
00150 return(mi_unique_comp(def, record, info->rec_buff,
00151 def->null_are_equal));
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 int _mi_read_static_record(register MI_INFO *info, register internal::my_off_t pos,
00161 register unsigned char *record)
00162 {
00163 int error;
00164
00165 if (pos != HA_OFFSET_ERROR)
00166 {
00167 if (info->opt_flag & WRITE_CACHE_USED &&
00168 info->rec_cache.pos_in_file <= pos &&
00169 flush_io_cache(&info->rec_cache))
00170 return(-1);
00171 info->rec_cache.seek_not_done=1;
00172
00173 error=info->s->file_read(info, record, info->s->base.reclength,
00174 pos,MYF(MY_NABP)) != 0;
00175 fast_mi_writeinfo(info);
00176 if (! error)
00177 {
00178 if (!*record)
00179 {
00180 errno=HA_ERR_RECORD_DELETED;
00181 return(1);
00182 }
00183 info->update|= HA_STATE_AKTIV;
00184 return(0);
00185 }
00186 return(-1);
00187 }
00188 fast_mi_writeinfo(info);
00189 return(-1);
00190 }
00191
00192
00193
00194 int _mi_read_rnd_static_record(MI_INFO *info, unsigned char *buf,
00195 register internal::my_off_t filepos,
00196 bool skip_deleted_blocks)
00197 {
00198 int locked,error,cache_read;
00199 uint32_t cache_length;
00200 MYISAM_SHARE *share=info->s;
00201
00202 cache_read=0;
00203 cache_length=0;
00204 if (info->opt_flag & WRITE_CACHE_USED &&
00205 (info->rec_cache.pos_in_file <= filepos || skip_deleted_blocks) &&
00206 flush_io_cache(&info->rec_cache))
00207 return(errno);
00208 if (info->opt_flag & READ_CACHE_USED)
00209 {
00210 if (filepos == my_b_tell(&info->rec_cache) &&
00211 (skip_deleted_blocks || !filepos))
00212 {
00213 cache_read=1;
00214 cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos);
00215 }
00216 else
00217 info->rec_cache.seek_not_done=1;
00218 }
00219 locked=0;
00220 if (info->lock_type == F_UNLCK)
00221 {
00222 if (filepos >= info->state->data_file_length)
00223 {
00224 if (_mi_readinfo(info,F_RDLCK,0))
00225 return(errno);
00226 locked=1;
00227 }
00228 else
00229 {
00230 #ifndef UNSAFE_LOCKING
00231 locked=1;
00232 #else
00233 info->tmp_lock_type=F_RDLCK;
00234 #endif
00235 }
00236 }
00237 if (filepos >= info->state->data_file_length)
00238 {
00239 fast_mi_writeinfo(info);
00240 return(errno=HA_ERR_END_OF_FILE);
00241 }
00242 info->lastpos= filepos;
00243 info->nextpos= filepos+share->base.pack_reclength;
00244
00245 if (! cache_read)
00246 {
00247 if ((error=_mi_read_static_record(info,filepos,buf)))
00248 {
00249 if (error > 0)
00250 error=errno=HA_ERR_RECORD_DELETED;
00251 else
00252 error=errno;
00253 }
00254 return(error);
00255 }
00256
00257
00258 error=my_b_read(&info->rec_cache,(unsigned char*) buf,share->base.reclength);
00259 if (info->s->base.pack_reclength != info->s->base.reclength && !error)
00260 {
00261 char tmp[8];
00262 error=my_b_read(&info->rec_cache,(unsigned char*) tmp,
00263 info->s->base.pack_reclength - info->s->base.reclength);
00264 }
00265 if (locked)
00266 _mi_writeinfo(info,0);
00267 if (!error)
00268 {
00269 if (!buf[0])
00270 {
00271 return(errno=HA_ERR_RECORD_DELETED);
00272 }
00273
00274 info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
00275 return(0);
00276 }
00277
00278 if (info->rec_cache.error != -1 || errno == 0)
00279 errno=HA_ERR_WRONG_IN_RECORD;
00280 return(errno);
00281 }