Exemple #1
0
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 */
Exemple #2
0
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 */
}