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 (info->rec_cache.write(record, info->s->base.reclength))
00053 goto err;
00054 if (info->s->base.pack_reclength != info->s->base.reclength)
00055 {
00056 uint32_t length=info->s->base.pack_reclength - info->s->base.reclength;
00057 memset(temp, 0, length);
00058 if (info->rec_cache.write(temp,length))
00059 goto err;
00060 }
00061 }
00062 else
00063 {
00064 info->rec_cache.seek_not_done=1;
00065 if (info->s->file_write(info, record, info->s->base.reclength,
00066 info->state->data_file_length,
00067 info->s->write_flag))
00068 goto err;
00069 if (info->s->base.pack_reclength != info->s->base.reclength)
00070 {
00071 uint32_t length=info->s->base.pack_reclength - info->s->base.reclength;
00072 memset(temp, 0, length);
00073 if (info->s->file_write(info, temp,length,
00074 info->state->data_file_length+
00075 info->s->base.reclength,
00076 info->s->write_flag))
00077 goto err;
00078 }
00079 }
00080 info->state->data_file_length+=info->s->base.pack_reclength;
00081 info->s->state.split++;
00082 }
00083 return 0;
00084 err:
00085 return 1;
00086 }
00087
00088 int _mi_update_static_record(MI_INFO *info, internal::my_off_t pos, const unsigned char *record)
00089 {
00090 info->rec_cache.seek_not_done=1;
00091 return (info->s->file_write(info,
00092 record, info->s->base.reclength,
00093 pos,
00094 MYF(MY_NABP)) != 0);
00095 }
00096
00097
00098 int _mi_delete_static_record(MI_INFO *info)
00099 {
00100 unsigned char temp[9];
00101
00102 info->state->del++;
00103 info->state->empty+=info->s->base.pack_reclength;
00104 temp[0]= '\0';
00105 _mi_dpointer(info,temp+1,info->s->state.dellink);
00106 info->s->state.dellink = info->lastpos;
00107 info->rec_cache.seek_not_done=1;
00108 return (info->s->file_write(info,(unsigned char*) temp, 1+info->s->rec_reflength,
00109 info->lastpos, MYF(MY_NABP)) != 0);
00110 }
00111
00112
00113 int _mi_cmp_static_record(register MI_INFO *info, register const unsigned char *old)
00114 {
00115 if (info->opt_flag & WRITE_CACHE_USED)
00116 {
00117 if (info->rec_cache.flush())
00118 {
00119 return(-1);
00120 }
00121 info->rec_cache.seek_not_done=1;
00122 }
00123
00124 if ((info->opt_flag & READ_CHECK_USED))
00125 {
00126 info->rec_cache.seek_not_done=1;
00127 if (info->s->file_read(info, info->rec_buff, info->s->base.reclength,
00128 info->lastpos,
00129 MYF(MY_NABP)))
00130 return(-1);
00131 if (memcmp(info->rec_buff, old,
00132 (uint) info->s->base.reclength))
00133 {
00134 errno=HA_ERR_RECORD_CHANGED;
00135 return(1);
00136 }
00137 }
00138 return(0);
00139 }
00140
00141
00142 int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def,
00143 const unsigned char *record, internal::my_off_t pos)
00144 {
00145 info->rec_cache.seek_not_done=1;
00146 if (info->s->file_read(info, info->rec_buff, info->s->base.reclength,
00147 pos, MYF(MY_NABP)))
00148 return(-1);
00149 return(mi_unique_comp(def, record, info->rec_buff,
00150 def->null_are_equal));
00151 }
00152
00153
00154
00155
00156
00157
00158
00159 int _mi_read_static_record(register MI_INFO *info, register internal::my_off_t pos,
00160 register unsigned char *record)
00161 {
00162 if (pos != HA_OFFSET_ERROR)
00163 {
00164 if (info->opt_flag & WRITE_CACHE_USED &&
00165 info->rec_cache.pos_in_file <= pos &&
00166 info->rec_cache.flush())
00167 return(-1);
00168 info->rec_cache.seek_not_done=1;
00169
00170 int error= info->s->file_read(info, record, info->s->base.reclength, pos,MYF(MY_NABP)) != 0;
00171 fast_mi_writeinfo(info);
00172 if (! error)
00173 {
00174 if (!*record)
00175 {
00176 errno=HA_ERR_RECORD_DELETED;
00177 return(1);
00178 }
00179 info->update|= HA_STATE_AKTIV;
00180 return(0);
00181 }
00182 return(-1);
00183 }
00184 fast_mi_writeinfo(info);
00185 return(-1);
00186 }
00187
00188
00189
00190 int _mi_read_rnd_static_record(MI_INFO *info, unsigned char *buf,
00191 register internal::my_off_t filepos,
00192 bool skip_deleted_blocks)
00193 {
00194 int locked,error,cache_read;
00195 MYISAM_SHARE *share=info->s;
00196
00197 cache_read=0;
00198 if (info->opt_flag & WRITE_CACHE_USED &&
00199 (info->rec_cache.pos_in_file <= filepos || skip_deleted_blocks) &&
00200 info->rec_cache.flush())
00201 return(errno);
00202 if (info->opt_flag & READ_CACHE_USED)
00203 {
00204 if (filepos == info->rec_cache.tell() &&
00205 (skip_deleted_blocks || !filepos))
00206 {
00207 cache_read=1;
00208 }
00209 else
00210 info->rec_cache.seek_not_done=1;
00211 }
00212 locked=0;
00213 if (info->lock_type == F_UNLCK)
00214 {
00215 if (filepos >= info->state->data_file_length)
00216 {
00217 if (_mi_readinfo(info,F_RDLCK,0))
00218 return(errno);
00219 locked=1;
00220 }
00221 else
00222 {
00223 #ifndef UNSAFE_LOCKING
00224 locked=1;
00225 #else
00226 info->tmp_lock_type=F_RDLCK;
00227 #endif
00228 }
00229 }
00230 if (filepos >= info->state->data_file_length)
00231 {
00232 fast_mi_writeinfo(info);
00233 return(errno=HA_ERR_END_OF_FILE);
00234 }
00235 info->lastpos= filepos;
00236 info->nextpos= filepos+share->base.pack_reclength;
00237
00238 if (! cache_read)
00239 {
00240 if ((error=_mi_read_static_record(info,filepos,buf)))
00241 {
00242 if (error > 0)
00243 error=errno=HA_ERR_RECORD_DELETED;
00244 else
00245 error=errno;
00246 }
00247 return(error);
00248 }
00249
00250
00251 error= info->rec_cache.read(buf, share->base.reclength);
00252 if (info->s->base.pack_reclength != info->s->base.reclength && !error)
00253 {
00254 char tmp[8];
00255 error= info->rec_cache.read(tmp, info->s->base.pack_reclength - info->s->base.reclength);
00256 }
00257 if (locked)
00258 _mi_writeinfo(info,0);
00259 if (!error)
00260 {
00261 if (!buf[0])
00262 {
00263 return(errno=HA_ERR_RECORD_DELETED);
00264 }
00265
00266 info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
00267 return(0);
00268 }
00269
00270 if (info->rec_cache.error != -1 || errno == 0)
00271 errno=HA_ERR_WRONG_IN_RECORD;
00272 return(errno);
00273 }