int mi_delete_all_rows(MI_INFO *info) { uint i; MYISAM_SHARE *share=info->s; MI_STATE_INFO *state=&share->state; DBUG_ENTER("mi_delete_all_rows"); if (share->options & HA_OPTION_READ_ONLY_DATA) { DBUG_RETURN(my_errno=EACCES); } if (_mi_readinfo(info,F_WRLCK,1)) DBUG_RETURN(my_errno); if (_mi_mark_file_changed(info)) goto err; info->state->records=info->state->del=state->split=0; state->dellink = HA_OFFSET_ERROR; state->sortkey= (ushort) ~0; info->state->key_file_length=share->base.keystart; info->state->data_file_length=0; info->state->empty=info->state->key_empty=0; info->state->checksum=0; for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; ) state->key_del[i]= HA_OFFSET_ERROR; for (i=0 ; i < share->base.keys ; i++) state->key_root[i]= HA_OFFSET_ERROR; myisam_log_command(MI_LOG_DELETE_ALL,info,(uchar*) 0,0,0); /* If we are using delayed keys or if the user has done changes to the tables since it was locked then there may be key blocks in the key cache */ flush_key_blocks(share->key_cache, share->kfile, FLUSH_IGNORE_CHANGED); #ifdef HAVE_MMAP if (share->file_map) mi_munmap_file(info); #endif if (my_chsize(info->dfile, 0, 0, MYF(MY_WME)) || my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)) ) goto err; VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); #ifdef HAVE_MMAP /* Map again */ if (share->file_map) mi_dynmap_file(info, (my_off_t) 0); #endif allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(0); err: { int save_errno=my_errno; VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); info->update|=HA_STATE_WRITTEN; /* Buffer changed */ allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(my_errno=save_errno); } } /* mi_delete */
int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo, N_RECINFO *recinfo, ulong records,ulong reloc, uint flags,uint old_options, ulong data_file_length) { register uint i,j; File dfile,file; int errpos,save_errno; uint fields,length,max_key_length,packed,pointer,reclength,min_pack_length, key_length,info_length,key_segs,options,min_key_length_skipp,max_block, base_pos; char buff[max(FN_REFLEN,512)]; ulong tot_length,pack_reclength; enum en_fieldtype type; ISAM_SHARE share; N_KEYDEF *keydef; N_KEYSEG *keyseg; N_RECINFO *rec; DBUG_ENTER("nisam_create"); LINT_INIT(dfile); pthread_mutex_lock(&THR_LOCK_isam); errpos=0; options=0; base_pos=512; /* Enough for N_STATE_INFO */ bzero((byte*) &share,sizeof(share)); if ((file = my_create(fn_format(buff,name,"",N_NAME_IEXT,4),0, O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) goto err; errpos=1; VOID(fn_format(buff,name,"",N_NAME_DEXT,2+4)); if (!(flags & HA_DONT_TOUCH_DATA)) { if ((dfile = my_create(buff,0,O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) goto err; errpos=2; } else if (!(old_options & HA_OPTION_TEMP_COMPRESS_RECORD)) options=old_options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA | HA_OPTION_PACK_RECORD); if (reloc > records) reloc=records; /* Check if wrong parameter */ /* Start by checking fields and field-types used */ reclength=0; for (rec=recinfo, fields=packed=min_pack_length=0, pack_reclength=0L; rec->base.type != (int) FIELD_LAST; rec++,fields++) { reclength+=rec->base.length; if ((type=(enum en_fieldtype) rec->base.type)) { packed++; if (type == FIELD_BLOB) { share.base.blobs++; rec->base.length-= sizeof(char*); /* Don't calc pointer */ if (pack_reclength != NI_POS_ERROR) { if (rec->base.length == 4) pack_reclength= (ulong) NI_POS_ERROR; else pack_reclength+=sizeof(char*)+(1 << (rec->base.length*8)); } } else if (type == FIELD_SKIP_PRESPACE || type == FIELD_SKIP_ENDSPACE) { if (pack_reclength != NI_POS_ERROR) pack_reclength+= rec->base.length > 255 ? 2 : 1; min_pack_length++; } else if (type == FIELD_ZERO) packed--; else if (type != FIELD_SKIP_ZERO) { min_pack_length+=rec->base.length; packed--; /* Not a pack record type */ } } else min_pack_length+=rec->base.length; } if ((packed & 7) == 1) { /* Bad packing, try to remove a zero-field */ while (rec != recinfo) { rec--; if (rec->base.type == (int) FIELD_SKIP_ZERO && rec->base.length == 1) { rec->base.type=(int) FIELD_NORMAL; packed--; min_pack_length++; break; } } } if (packed && !(options & HA_OPTION_COMPRESS_RECORD)) options|=HA_OPTION_PACK_RECORD; /* Must use packed records */ packed=(packed+7)/8; if (pack_reclength != NI_POS_ERROR) pack_reclength+= reclength+packed; min_pack_length+=packed; if (options & HA_OPTION_COMPRESS_RECORD) { if (data_file_length >= (1L << 24)) pointer=4; else if (data_file_length >= (1L << 16)) pointer=3; else pointer=2; } else if (((records == 0L && pack_reclength < 255) || options & HA_OPTION_PACK_RECORD) || records >= (ulong) 16000000L || pack_reclength == (ulong) NI_POS_ERROR || ((options & HA_OPTION_PACK_RECORD) && pack_reclength+4 >= (ulong) 14000000L/records)) pointer=4; else if (records == 0L || records >= (ulong) 65000L || ((options & HA_OPTION_PACK_RECORD) && pack_reclength+4 >= (ulong) 60000L/records)) pointer=3; else pointer=2; max_block=max_key_length=0; tot_length=key_segs=0; for (i=0, keydef=keyinfo ; i < keys ; i++ , keydef++) { share.state.key_root[i]= share.state.key_del[i]= NI_POS_ERROR; share.base.rec_per_key[i]= (keydef->base.flag & HA_NOSAME) ? 1L : 0L; min_key_length_skipp=length=0; key_length=pointer; if (keydef->base.flag & HA_PACK_KEY && keydef->seg[0].base.length > 127) keydef->base.flag&= ~HA_PACK_KEY; /* Can't pack long keys */ if (keydef->base.flag & HA_PACK_KEY) { if ((keydef->seg[0].base.flag & HA_SPACE_PACK) && keydef->seg[0].base.type == (int) HA_KEYTYPE_NUM) keydef->seg[0].base.flag&= ~HA_SPACE_PACK; if (!(keydef->seg[0].base.flag & HA_SPACE_PACK)) length++; keydef->seg[0].base.flag|=HA_PACK_KEY; /* for easyer intern test */ options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ if (!(keydef->seg[0].base.flag & HA_SPACE_PACK)) min_key_length_skipp+=keydef->seg[0].base.length; } keydef->base.keysegs=0; for (keyseg=keydef->seg ; keyseg->base.type ; keyseg++) { keydef->base.keysegs++; if (keyseg->base.length > 127) keyseg->base.flag&= ~(HA_SPACE_PACK | HA_PACK_KEY); if (keyseg->base.flag & HA_SPACE_PACK) { keydef->base.flag |= HA_SPACE_PACK_USED; options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ length++; min_key_length_skipp+=keyseg->base.length; } key_length+= keyseg->base.length; } bzero((gptr) keyseg,sizeof(keyseg[0])); keyseg->base.length=(uint16) pointer; /* Last key part is pointer */ key_segs+=keydef->base.keysegs; length+=key_length; keydef->base.block_length=nisam_block_size; keydef->base.keylength= (uint16) key_length; keydef->base.minlength= (uint16) (length-min_key_length_skipp); keydef->base.maxlength= (uint16) length; if ((uint) keydef->base.block_length > max_block) max_block=(uint) keydef->base.block_length; if (length > max_key_length) max_key_length= length; tot_length+= (records/(ulong) (((uint) keydef->base.block_length-5)/ (length*2)))* (ulong) keydef->base.block_length; } info_length=(uint) (base_pos+sizeof(N_BASE_INFO)+keys*sizeof(N_SAVE_KEYDEF)+ (keys+key_segs)*sizeof(N_SAVE_KEYSEG)+ fields*sizeof(N_SAVE_RECINFO)); bmove(share.state.header.file_version,(byte*) nisam_file_magic,4); old_options=options| (old_options & HA_OPTION_TEMP_COMPRESS_RECORD ? HA_OPTION_COMPRESS_RECORD | HA_OPTION_TEMP_COMPRESS_RECORD: 0); int2store(share.state.header.options,old_options); int2store(share.state.header.header_length,info_length); int2store(share.state.header.state_info_length,sizeof(N_STATE_INFO)); int2store(share.state.header.base_info_length,sizeof(N_BASE_INFO)); int2store(share.state.header.base_pos,base_pos); share.state.dellink = NI_POS_ERROR; share.state.process= (ulong) getpid(); share.state.uniq= (ulong) file; share.state.loop= 0; share.state.version= (ulong) time((time_t*) 0); share.base.options=options; share.base.rec_reflength=pointer; share.base.key_reflength=((!tot_length || tot_length > 30000000L) ? 3 : tot_length > 120000L ? 2 : 1); share.base.keys= share.state.keys = keys; share.base.keystart = share.state.key_file_length=MY_ALIGN(info_length, nisam_block_size); share.base.max_block=max_block; share.base.max_key_length=(uint) ALIGN_SIZE(max_key_length+4); share.base.records=records; share.base.reloc=reloc; share.base.reclength=reclength; share.base.pack_reclength= (uint) (reclength+packed-share.base.blobs*sizeof(char*)); share.base.max_pack_length=pack_reclength; share.base.min_pack_length=min_pack_length; share.base.pack_bits=packed; share.base.fields=fields; share.base.pack_fields=packed; share.base.sortkey= (ushort) ~0; share.base.max_data_file_length= (pointer == 4) ? (ulong) ~0L : (options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? (ulong) (1L << (pointer*8)) : (pointer == 3 && reclength >= 256L) ? (ulong) NI_POS_ERROR : ((ulong) reclength * (1L << (pointer*8))); share.base.max_key_file_length= (share.base.key_reflength == 3 ? NI_POS_ERROR : (ulong) (1L << (share.base.key_reflength*8))*512); share.base.min_block_length= (share.base.pack_reclength+3 < N_EXTEND_BLOCK_LENGTH && ! share.base.blobs) ? max(share.base.pack_reclength,N_MIN_BLOCK_LENGTH) : N_EXTEND_BLOCK_LENGTH; if (! (flags & HA_DONT_TOUCH_DATA)) share.base.create_time= (long) time((time_t*) 0); bzero(buff,base_pos); if (my_write(file,(char*) &share.state,sizeof(N_STATE_INFO),MYF(MY_NABP)) || my_write(file,buff,base_pos-sizeof(N_STATE_INFO),MYF(MY_NABP)) || my_write(file,(char*) &share.base,sizeof(N_BASE_INFO),MYF(MY_NABP))) goto err; for (i=0 ; i < share.base.keys ; i++) { if (my_write(file,(char*) &keyinfo[i].base,sizeof(N_SAVE_KEYDEF), MYF(MY_NABP))) goto err; for (j=0 ; j <= keyinfo[i].base.keysegs ; j++) { if (my_write(file,(char*) &keyinfo[i].seg[j].base,sizeof(N_SAVE_KEYSEG), MYF(MY_NABP))) goto err; } } for (i=0 ; i < share.base.fields ; i++) if (my_write(file,(char*) &recinfo[i].base, (uint) sizeof(N_SAVE_RECINFO), MYF(MY_NABP))) goto err; /* Enlarge files */ if (my_chsize(file, (ulong) share.base.keystart, 0, MYF(0))) goto err; if (! (flags & HA_DONT_TOUCH_DATA)) { #ifdef USE_RELOC if (my_chsize(dfile, share.base.min_pack_length*reloc, 0, MYF(0))) goto err; #endif errpos=1; if (my_close(dfile,MYF(0))) goto err; } errpos=0; pthread_mutex_unlock(&THR_LOCK_isam); if (my_close(file,MYF(0))) goto err; DBUG_RETURN(0); err: pthread_mutex_unlock(&THR_LOCK_isam); save_errno=my_errno; switch (errpos) { case 2: VOID(my_close(dfile,MYF(0))); /* fall through */ case 1: VOID(my_close(file,MYF(0))); } my_errno=save_errno; /* R{tt felkod tillbaka */ DBUG_RETURN(-1); } /* nisam_create */
int modify_defaults_file(const char *file_location, const char *option, const char *option_value, const char *section_name, int remove_option) { FILE *cnf_file; MY_STAT file_stat; char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer; size_t opt_len= 0, optval_len= 0, sect_len; uint nr_newlines= 0, buffer_size; my_bool in_section= FALSE, opt_applied= 0; uint reserve_extended; uint new_opt_len; int reserve_occupied= 0; DBUG_ENTER("modify_defaults_file"); if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0)))) DBUG_RETURN(2); /* my_fstat doesn't use the flag parameter */ if (my_fstat(fileno(cnf_file), &file_stat, MYF(0))) goto malloc_err; if (option && option_value) { opt_len= strlen(option); optval_len= strlen(option_value); } new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN; /* calculate the size of the buffer we need */ reserve_extended= (opt_len + 1 + /* For '=' char */ optval_len + /* Option value len */ NEWLINE_LEN + /* Space for newline */ RESERVE); /* Some additional space */ buffer_size= (file_stat.st_size + 1); /* The ending zero */ /* Reserve space to read the contents of the file and some more for the option we want to add. */ if (!(file_buffer= (char*) my_malloc(buffer_size + reserve_extended, MYF(MY_WME)))) goto malloc_err; sect_len= strlen(section_name); for (dst_ptr= file_buffer; fgets(linebuff, BUFF_SIZE, cnf_file); ) { /* Skip over whitespaces */ for (src_ptr= linebuff; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++) {} if (!*src_ptr) /* Empty line */ { nr_newlines++; continue; } /* correct the option (if requested) */ if (option && in_section && !strncmp(src_ptr, option, opt_len) && (*(src_ptr + opt_len) == '=' || my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) || *(src_ptr + opt_len) == '\0')) { char *old_src_ptr= src_ptr; src_ptr= strend(src_ptr+ opt_len); /* Find the end of the line */ /* could be negative */ reserve_occupied+= (int) new_opt_len - (int) (src_ptr - old_src_ptr); if (reserve_occupied >= (int) reserve_extended) { reserve_extended= (uint) reserve_occupied + RESERVE; if (!(file_buffer= (char*) my_realloc(file_buffer, buffer_size + reserve_extended, MYF(MY_WME|MY_FREE_ON_ERROR)))) goto malloc_err; } opt_applied= 1; dst_ptr= add_option(dst_ptr, option_value, option, remove_option); } else { /* If we are going to the new group and have an option to apply, do it now. If we are removing a single option or the whole section this will only trigger opt_applied flag. */ if (in_section && !opt_applied && *src_ptr == '[') { dst_ptr= add_option(dst_ptr, option_value, option, remove_option); opt_applied= 1; /* set the flag to do write() later */ reserve_occupied= new_opt_len+ opt_len + 1 + NEWLINE_LEN; } for (; nr_newlines; nr_newlines--) dst_ptr= strmov(dst_ptr, NEWLINE); /* Skip the section if MY_REMOVE_SECTION was given */ if (!in_section || remove_option != MY_REMOVE_SECTION) dst_ptr= strmov(dst_ptr, linebuff); } /* Look for a section */ if (*src_ptr == '[') { /* Copy the line to the buffer */ if (!strncmp(++src_ptr, section_name, sect_len)) { src_ptr+= sect_len; /* Skip over whitespaces. They are allowed after section name */ for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++) {} if (*src_ptr != ']') { in_section= FALSE; continue; /* Missing closing parenthesis. Assume this was no group */ } if (remove_option == MY_REMOVE_SECTION) dst_ptr= dst_ptr - strlen(linebuff); in_section= TRUE; } else in_section= FALSE; /* mark that this section is of no interest to us */ } } /* File ended. Apply an option or set opt_applied flag (in case of MY_REMOVE_SECTION) so that the changes are saved. Do not do anything if we are removing non-existent option. */ if (!opt_applied && in_section && (remove_option != MY_REMOVE_OPTION)) { /* New option still remains to apply at the end */ if (!remove_option && *(dst_ptr - 1) != '\n') dst_ptr= strmov(dst_ptr, NEWLINE); dst_ptr= add_option(dst_ptr, option_value, option, remove_option); opt_applied= 1; } for (; nr_newlines; nr_newlines--) dst_ptr= strmov(dst_ptr, NEWLINE); if (opt_applied) { /* Don't write the file if there are no changes to be made */ if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, MYF(MY_WME)) || my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer), MYF(MY_NABP))) goto err; } if (my_fclose(cnf_file, MYF(MY_WME))) DBUG_RETURN(1); my_free(file_buffer, MYF(0)); DBUG_RETURN(0); err: my_free(file_buffer, MYF(0)); malloc_err: my_fclose(cnf_file, MYF(0)); DBUG_RETURN(1); /* out of resources */ }