Пример #1
0
 bool FileRecord::Remove(const std::string& id, const std::string& owner) {
   if(!valid_) return false;
   Glib::Mutex::Lock lock(lock_);
   Dbt key;
   Dbt data;
   make_key(id,owner,key);
   void* pkey = key.get_data();
   if(dberr("",db_locked_->get(NULL,&key,&data,0))) {
     ::free(pkey);
     error_str_ = "Record has active locks";
     return false; // have locks
   };
   if(!dberr("Failed to retrieve record from database",db_rec_->get(NULL,&key,&data,0))) {
     ::free(pkey);
     return false; // No such record?
   };
   std::string uid;
   std::string id_tmp;
   std::string owner_tmp;
   std::list<std::string> meta;
   parse_record(uid,id_tmp,owner_tmp,meta,key,data);
   if(!uid.empty()) {
     ::unlink(uid_to_path(uid).c_str()); // TODO: handle error
   };
   if(!dberr("Failed to delete record from database",db_rec_->del(NULL,&key,0))) {
     // TODO: handle error
     ::free(pkey);
     return false;
   };
   db_rec_->sync(0);
   ::free(pkey);
   return true;
 }
Пример #2
0
 bool FileRecord::RemoveLock(const std::string& lock_id, std::list<std::pair<std::string,std::string> >& ids) {
   if(!valid_) return false;
   Glib::Mutex::Lock lock(lock_);
   Dbc* cur = NULL;
   if(!dberr("removelock:cursor",db_lock_->cursor(NULL,&cur,DB_WRITECURSOR))) return false;
   Dbt key;
   Dbt data;
   make_string(lock_id,key);
   void* pkey = key.get_data();
   if(!dberr("removelock:get1",cur->get(&key,&data,DB_SET))) { // TODO: handle errors
     ::free(pkey);
     cur->close(); return false;
   };
   for(;;) {
     std::string id;
     std::string owner;
     uint32_t size = data.get_size();
     void* buf = data.get_data();
     buf = parse_string(id,buf,size);
     buf = parse_string(owner,buf,size);
     ids.push_back(std::pair<std::string,std::string>(id,owner));
     if(!dberr("removelock:del",cur->del(0))) {
       ::free(pkey);
       cur->close(); return false;
     };
     if(!dberr("removelock:get2",cur->get(&key,&data,DB_NEXT_DUP))) break;
   };
   db_lock_->sync(0);
   ::free(pkey);
   cur->close();
   return true;
 }
Пример #3
0
 bool FileRecord::Modify(const std::string& id, const std::string& owner, const std::list<std::string>& meta) {
   if(!valid_) return false;
   Glib::Mutex::Lock lock(lock_);
   Dbt key;
   Dbt data;
   make_key(id,owner,key);
   void* pkey = key.get_data();
   if(!dberr("Failed to retrieve record from database",db_rec_->get(NULL,&key,&data,0))) {
     ::free(pkey);
     return false;
   };
   std::string uid;
   std::string id_tmp;
   std::string owner_tmp;
   std::list<std::string> meta_tmp;
   parse_record(uid,id_tmp,owner_tmp,meta_tmp,key,data);
   ::free(pkey);
   make_record(uid,id,owner,meta,key,data);
   if(!dberr("Failed to store record to database",db_rec_->put(NULL,&key,&data,0))) {
     ::free(key.get_data());
     ::free(data.get_data());
     return false;
   };
   db_rec_->sync(0);
   ::free(key.get_data());
   ::free(data.get_data());
   return true;
 }
Пример #4
0
 bool FileRecord::verify(void) {
   // Performing various kinds of verifications
   std::string dbpath = basepath_ + G_DIR_SEPARATOR_S + FR_DB_NAME;
   {
     Db db_test(NULL,DB_CXX_NO_EXCEPTIONS);
     if(!dberr("Error verifying databases",
               db_test.verify(dbpath.c_str(),NULL,NULL,DB_NOORDERCHK))) {
       if(error_num_ != ENOENT) return false;
     };
   };
   {
     Db db_test(NULL,DB_CXX_NO_EXCEPTIONS);
     if(!dberr("Error verifying database 'meta'",
               db_test.verify(dbpath.c_str(),"meta",NULL,DB_ORDERCHKONLY))) {
       if(error_num_ != ENOENT) return false;
     };
   };
   // Skip 'link' - it is not of btree kind
   // Skip 'lock' - for unknown reason it returns DB_NOTFOUND
   // Skip 'locked' - for unknown reason it returns DB_NOTFOUND
   return true;
 }
Пример #5
0
 bool FileRecord::AddLock(const std::string& lock_id, const std::list<std::string>& ids, const std::string& owner) {
   if(!valid_) return false;
   Glib::Mutex::Lock lock(lock_);
   Dbt key;
   Dbt data;
   for(std::list<std::string>::const_iterator id = ids.begin(); id != ids.end(); ++id) {
     make_link(lock_id,*id,owner,data);
     void* pdata = data.get_data();
     if(!dberr("addlock:put",db_link_->put(NULL,&key,&data,DB_APPEND))) {
       ::free(pdata);
       return false;
     };
     ::free(pdata);
   };
   db_link_->sync(0);
   return true;
 }
Пример #6
0
 std::string FileRecord::Find(const std::string& id, const std::string& owner, std::list<std::string>& meta) {
   if(!valid_) return "";
   Glib::Mutex::Lock lock(lock_);
   Dbt key;
   Dbt data;
   make_key(id,owner,key);
   void* pkey = key.get_data();
   if(!dberr("Failed to retrieve record from database",db_rec_->get(NULL,&key,&data,0))) {
     ::free(pkey);
     return "";
   };
   std::string uid;
   std::string id_tmp;
   std::string owner_tmp;
   parse_record(uid,id_tmp,owner_tmp,meta,key,data);
   ::free(pkey);
   return uid_to_path(uid);
 }
Пример #7
0
 std::string FileRecord::Add(std::string& id, const std::string& owner, const std::list<std::string>& meta) {
   if(!valid_) return "";
   Glib::Mutex::Lock lock(lock_);
   Dbt key;
   Dbt data;
   std::string uid = rand_uid64().substr(4);
   make_record(uid,(id.empty())?uid:id,owner,meta,key,data);
   void* pkey = key.get_data();
   void* pdata = data.get_data();
   if(!dberr("Failed to add record to database",db_rec_->put(NULL,&key,&data,DB_NOOVERWRITE))) {
     ::free(pkey); ::free(pdata);
     return "";
   };
   db_rec_->sync(0);
   ::free(pkey); ::free(pdata);
   if(id.empty()) id = uid;
   return uid_to_path(uid);
 }
Пример #8
0
/* Initialize database tables
*/
int
inittab()
{
   register int dbt_lc;			/* loop control */
   register INT i, j;
   int key_offset = 0, key_count;
   char dbfile[DtSrFILENMLEN], dbd_ver[DBD_COMPAT_LEN + 1];
   char dbname[FILENMLEN];	/* Temporary working space */
   int dbf;
   FILE_ENTRY FAR *file_ptr;
   FIELD_ENTRY FAR *fld_ptr;
#ifndef	 ONE_DB
#define	 DB_ENABLE   1
#else
#define	 DB_ENABLE   0
#endif
#ifndef	 NO_TIMESTAMP
#define	 TS_ENABLE   1
#else
#define	 TS_ENABLE   0
#endif
#if   DB_ENABLE | TS_ENABLE
   RECORD_ENTRY FAR *rec_ptr;
   SET_ENTRY FAR *set_ptr;
#endif
#ifndef	 ONE_DB
   MEMBER_ENTRY FAR *mem_ptr;
   SORT_ENTRY FAR *srt_ptr;
   KEY_ENTRY FAR *key_ptr;
#endif

#ifndef	 NO_TIMESTAMP
   db_tsrecs = db_tssets = FALSE;
#endif
   size_ft = size_rt = size_st = size_mt = size_srt = size_fd = size_kt = 0;

   /* compute individual dictionary sizes and offsets */
#ifndef	 ONE_DB
   for (dbt_lc = 0, curr_db_table = &db_table[old_no_of_dbs]; 
	dbt_lc < no_of_dbs; ++dbt_lc, ++curr_db_table) {
#endif

      /* form database dictionary name */
      if ( DB_REF(db_path[0]) )
	 strcpy(dbname, DB_REF(db_path));
      else
	 dbname[0] = '\0';

#ifdef DEBUG_INITTAB
      if (debugging_inittab) {
	    printf (__FILE__"100 inittab: path='%s' dbname='%s'\n",
		dbname, DB_REF(db_name));
	    fflush (stdout);
      }
#endif
      if (strlen(dbname) + strlen(DB_REF(db_name)) >= FILENMLEN+4)
	 return( dberr(S_NAMELEN) );
      strcat(dbname, DB_REF(db_name));
      if (con_dbd(dbfile, dbname, get_element(dbdpath, dbt_lc)) != S_OKAY)
	 return( dberr(db_status) );

      /*----------------- PASS 1 -------------------
       * In this first pass, only opening to determine
       * required table sizes, so opening read-only is ok.
       */
      if ( (dbf = open_b(dbfile, O_RDONLY)) < 0 )
	 return( dberr( S_INVDB ) );

      /* Read in and verify the dictionary version */
      DB_READ(dbf, dbd_ver, DBD_COMPAT_LEN);
      dbd_ver[DBD_COMPAT_LEN] = '\0';
      for ( i=0; i<size_compat; i++ ) {
	 if ( strcmp( dbd_ver, compat_dbd[i] ) == 0 ) goto goodver;
      }

      /* Incompatible dictionary file */
      close( dbf );
      return( dberr( S_INCOMPAT ) );
goodver:

      /* Read in database page size */
      DB_READ(dbf, (char FAR *)&DB_REF(Page_size), sizeof(INT));
      NTOHS (DB_REF(Page_size));

      /* Read in table sizes */
      DB_READ(dbf, (char FAR *)&DB_REF(Size_ft), sizeof(INT));
      NTOHS (DB_REF(Size_ft));
      DB_READ(dbf, (char FAR *)&DB_REF(Size_rt), sizeof(INT));
      NTOHS (DB_REF(Size_rt));
      DB_READ(dbf, (char FAR *)&DB_REF(Size_fd), sizeof(INT));
      NTOHS (DB_REF(Size_fd));
      DB_READ(dbf, (char FAR *)&DB_REF(Size_st), sizeof(INT));
      NTOHS (DB_REF(Size_st));
      DB_READ(dbf, (char FAR *)&DB_REF(Size_mt), sizeof(INT));
      NTOHS (DB_REF(Size_mt));
      DB_READ(dbf, (char FAR *)&DB_REF(Size_srt), sizeof(INT));
      NTOHS (DB_REF(Size_srt));
      DB_READ(dbf, (char FAR *)&DB_REF(Size_kt), sizeof(INT));
      NTOHS (DB_REF(Size_kt));
      close(dbf);	/* end of PASS 1 */

#ifdef DEBUG_INITTAB
      if (debugging_inittab) {
	 printf (__FILE__"152 sizes: pg=%d ft=%d rt=%d fd=%d\n"
	    "  st=%d mt=%d srt=%d kt=%d\n",
	    (int) DB_REF(Page_size),
	    (int) DB_REF(Size_ft),
	    (int) DB_REF(Size_rt),
	    (int) DB_REF(Size_fd),
	    (int) DB_REF(Size_st),
	    (int) DB_REF(Size_mt),
	    (int) DB_REF(Size_srt),
	    (int) DB_REF(Size_kt)
	    );
	  fflush (stdout);
      }
#endif

      DB_REF(sysdba) = NULL_DBA;

#ifndef	 ONE_DB
      /* update merged dictionary offsets and sizes */
      if ( curr_db_table->Page_size > page_size ) {
	    page_size = curr_db_table->Page_size;
#ifdef DEBUG_INITTAB
	    if (debugging_inittab) {
		printf (__FILE__"191 db's page_size-->%d (largest = %d)\n",
		    (int)page_size, (int)largest_page);
		fflush(stdout);
	    }
#endif
      }

      curr_db_table->ft_offset = size_ft;
      size_ft += curr_db_table->Size_ft;
      curr_db_table->rt_offset = size_rt;
      size_rt += curr_db_table->Size_rt;
      curr_db_table->fd_offset = size_fd;
      size_fd += curr_db_table->Size_fd;
      curr_db_table->st_offset = size_st;
      size_st += curr_db_table->Size_st;
      curr_db_table->mt_offset = size_mt;
      size_mt += curr_db_table->Size_mt;
      curr_db_table->srt_offset = size_srt;
      size_srt += curr_db_table->Size_srt;
      curr_db_table->kt_offset = size_kt;
      size_kt += curr_db_table->Size_kt;
   }
#endif
   /* allocate dictionary space */
   if ( alloc_dict() != S_OKAY ) return( db_status );

   /* read in and adjust dictionary entries for each database */
#ifndef	 ONE_DB
   for (dbt_lc = 0, curr_db_table = &db_table[old_no_of_dbs]; 
	dbt_lc < no_of_dbs; 
	++dbt_lc, ++curr_db_table) {
#endif

      /* form database dictionary name */
      if ( DB_REF(db_path[0]) )
	 strcpy(dbname, DB_REF(db_path));
      else
	 dbname[0] = '\0';
      if (strlen(dbname) + strlen(DB_REF(db_name)) >= FILENMLEN+4)
	 return( dberr(S_NAMELEN) );
      strcat(dbname,DB_REF(db_name));
      if (con_dbd(dbfile,dbname,get_element(dbdpath, dbt_lc)) != S_OKAY)
	 return( dberr(db_status) );
#ifdef DEBUG_INITTAB
      if (dump_init_tables) {
	printf (__FILE__"247 Tables for database '%s':\n", dbfile);
	fflush (stdout);
      }
#endif

      /*----------------- PASS 2 -------------------
       * Second pass just loads allocated tables,
       * so opening .dbd file read-only is still ok.
       */
      dbf = open_b (dbfile, O_RDONLY);
      DB_LSEEK(dbf, DBD_COMPAT_LEN + 8L*sizeof(INT), 0);

      /*----------------- FILE TABLE -------------------*/
      DB_READ(dbf, (char FAR *)&file_table[ORIGIN(ft_offset)],
	    (DB_REF(Size_ft)*sizeof(FILE_ENTRY)));
      /* Invalid if sizeof(xxxx_ENTRY) diff on each machine */
      for (	i = 0, file_ptr = &file_table[ORIGIN(ft_offset)];
		i < DB_REF(Size_ft);
		i++, file_ptr++) {
	    /* Byte swap each INT on LITTLE_ENDIAN machines */
	    NTOHS (file_ptr->ft_slots);
	    NTOHS (file_ptr->ft_slsize);
	    NTOHS (file_ptr->ft_pgsize);
	    NTOHS (file_ptr->ft_flags);
#ifdef DEBUG_INITTAB
	    if (dump_init_tables) {
		printf (" FILE#%d: ty=%c slts=%2d slsz=%3d pgsz=%d '%s'\n",
		    (int)i,
		    file_ptr->ft_type,
		    (int)file_ptr->ft_slots,
		    (int)file_ptr->ft_slsize,
		    (int)file_ptr->ft_pgsize,
		    file_ptr->ft_name);
		fflush (stdout);
	    }
#endif
      }

      /*----------------- RECORD TABLE -------------------*/
      DB_READ(dbf, (char FAR *)&record_table[ORIGIN(rt_offset)],
	   (DB_REF(Size_rt)*sizeof(RECORD_ENTRY)));
      for (	i = 0, rec_ptr = &record_table[ORIGIN(rt_offset)];
		i < DB_REF(Size_rt);
		i++, rec_ptr++) {
	    /* Byte swap each INT on LITTLE_ENDIAN machines */
	    NTOHS (rec_ptr->rt_file);
	    NTOHS (rec_ptr->rt_len);
	    NTOHS (rec_ptr->rt_data);
	    NTOHS (rec_ptr->rt_fields);
	    NTOHS (rec_ptr->rt_fdtot);
	    NTOHS (rec_ptr->rt_flags);
#ifdef DEBUG_INITTAB
	    if (dump_init_tables) {
		printf (
		    " REC #%d: fil=%d len=%3d data=%2d fld1=%2d flds=%2d\n",
		    (int)i,
		    (int)rec_ptr->rt_file,
		    (int)rec_ptr->rt_len,
		    (int)rec_ptr->rt_data,
		    (int)rec_ptr->rt_fields,
		    (int)rec_ptr->rt_fdtot);
		fflush (stdout);
	    }
#endif
      }

      /*----------------- FIELD TABLE -------------------*/
      DB_READ(dbf, (char FAR *)&field_table[ORIGIN(fd_offset)],
	   (DB_REF(Size_fd)*sizeof(FIELD_ENTRY)));
      for (	i = 0, fld_ptr = &field_table[ORIGIN(fd_offset)];
		i < DB_REF(Size_fd);
		i++, fld_ptr++) {
	    /* Byte swap each INT on LITTLE_ENDIAN machines */
	    NTOHS (fld_ptr->fd_len);
	    NTOHS (fld_ptr->fd_keyfile);
	    NTOHS (fld_ptr->fd_keyno);
	    NTOHS (fld_ptr->fd_ptr);
	    NTOHS (fld_ptr->fd_rec);
	    NTOHS (fld_ptr->fd_flags);
	    for (j=0;  j<MAXDIMS;  j++)
	        NTOHS (fld_ptr->fd_dim[j]);
#ifdef DEBUG_INITTAB
	    if (dump_init_tables) {
		if (i == 0)
		    puts ("         key typ len kfil key# ofs rec# flg dims");
		printf (
		    " FLD#%2d  %c   %c  %3d  %d    %d   %3d  %d    %x",
		    (int)i,
		    fld_ptr->fd_key,
		    fld_ptr->fd_type,
		    (int)fld_ptr->fd_len,
		    (int)fld_ptr->fd_keyfile,
		    (int)fld_ptr->fd_keyno,
		    (int)fld_ptr->fd_ptr,
		    (int)fld_ptr->fd_rec,
		    (int)fld_ptr->fd_flags);
		for (j=0; j<MAXDIMS; j++)
		    if (fld_ptr->fd_dim[j])
			printf (" %d:%d", j, (int)fld_ptr->fd_dim[j]);
		putchar ('\n');
		fflush (stdout);
	    }
#endif
      }

      /*----------------- SET TABLE -------------------*/
      DB_READ(dbf, (char FAR *)&set_table[ORIGIN(st_offset)],
	   (DB_REF(Size_st)*sizeof(SET_ENTRY)));
      for (	i = 0, set_ptr = &set_table[ORIGIN(st_offset)];
		i < DB_REF(Size_st);
		i++, set_ptr++) {
	    /* Byte swap each INT on LITTLE_ENDIAN machines */
	    NTOHS (set_ptr->st_order);
	    NTOHS (set_ptr->st_own_rt);
	    NTOHS (set_ptr->st_own_ptr);
	    NTOHS (set_ptr->st_members);
	    NTOHS (set_ptr->st_memtot);
	    NTOHS (set_ptr->st_flags);
#ifdef DEBUG_INITTAB
	    if (dump_init_tables) {
		printf (
		    " SET #%d: ord=%c owner=%d ownofs=%2d mem1=%d mems=%d\n",
		    (int)i,
		    (char)set_ptr->st_order,
		    (int)set_ptr->st_own_rt,
		    (int)set_ptr->st_own_ptr,
		    (int)set_ptr->st_members,
		    (int)set_ptr->st_memtot);
		fflush (stdout);
	    }
#endif
      }

      /*----------------- MEMBER TABLE -------------------*/
      DB_READ(dbf, (char FAR *)&member_table[ORIGIN(mt_offset)],
	   (DB_REF(Size_mt)*sizeof(MEMBER_ENTRY)));
      for (	i = 0, mem_ptr = &member_table[ORIGIN(mt_offset)];
		i < DB_REF(Size_mt);
		i++, mem_ptr++) {
	    /* Byte swap each INT on LITTLE_ENDIAN machines */
	    NTOHS (mem_ptr->mt_record);
	    NTOHS (mem_ptr->mt_mem_ptr);
	    NTOHS (mem_ptr->mt_sort_fld);
	    NTOHS (mem_ptr->mt_totsf);
#ifdef DEBUG_INITTAB
	    if (dump_init_tables) {
		printf (
		    " MEM #%d: rec=%d ofs=%d sort1=%d sorts=%d\n",
		    (int)i,
		    (int)mem_ptr->mt_record,
		    (int)mem_ptr->mt_mem_ptr,
		    (int)mem_ptr->mt_sort_fld,
		    (int)mem_ptr->mt_totsf);
		fflush (stdout);
	    }
#endif
      }


      DB_READ(dbf, (char FAR *)&sort_table[ORIGIN(srt_offset)],
	   (DB_REF(Size_srt)*sizeof(SORT_ENTRY)));
      /* Member sort tables not used by DtSearch @@@ */
      if (DB_REF(Size_srt)) {
    	    /* Byte swap each INT on LITTLE_ENDIAN machines */
	    srt_ptr = &sort_table[ORIGIN(srt_offset)];
	    NTOHS (srt_ptr->se_fld);
	    NTOHS (srt_ptr->se_set);
      }

      DB_READ(dbf, (char FAR *)&key_table[ORIGIN(kt_offset)],
	   (DB_REF(Size_kt)*sizeof(KEY_ENTRY)));
      /* Compound key tables not used by DtSearch @@@ */
      if (DB_REF(Size_kt)) {
	    /* Byte swap each INT on LITTLE_ENDIAN machines */
	    key_ptr = &key_table[ORIGIN(kt_offset)];
	    NTOHS (key_ptr->kt_key);
	    NTOHS (key_ptr->kt_field);
	    NTOHS (key_ptr->kt_ptr);
	    NTOHS (key_ptr->kt_sort);
      }

      close(dbf);	/* end of PASS 2 */
#ifdef DEBUG_INITTAB
      dump_init_tables = FALSE;
#endif
#ifndef	 ONE_DB
      curr_db_table->key_offset = key_offset;
#endif

      /* update file table path entries */
      if ( DB_REF(db_path[0]) || dbfpath[0] ) {
	 for (i = 0, file_ptr = &file_table[ORIGIN(ft_offset)];
	      i < DB_REF(Size_ft);
	      ++i, ++file_ptr) {

	    /* Construct the data/key file name */
	    if ( DB_REF(db_path[0]) )
	       strcpy(dbname, DB_REF(db_path));
	    else
	       dbname[0] = '\0';
	    if (strlen(dbname) + strlen(DB_REF(db_name)) >= FILENMLEN+4)
	       return( dberr(S_NAMELEN) );
	    strcat(dbname, DB_REF(db_name));
	    if (con_dbf(dbfile, file_ptr->ft_name, dbname,
	       get_element(dbfpath, dbt_lc)) != S_OKAY)
	       return( dberr(db_status) );

	    /* Save new name in dictionary */
	    strcpy(file_ptr->ft_name, dbfile);
	 } 
      }
#if   DB_ENABLE | TS_ENABLE
      /* adjust record table entries */
      for (i = ORIGIN(rt_offset), rec_ptr = &record_table[ORIGIN(rt_offset)];
	   i < ORIGIN(rt_offset) + DB_REF(Size_rt);
	   ++i, ++rec_ptr) {
#ifndef	 ONE_DB
	 rec_ptr->rt_file += curr_db_table->ft_offset;
	 rec_ptr->rt_fields += curr_db_table->fd_offset;
#endif
#ifndef	 NO_TIMESTAMP
	 if ( rec_ptr->rt_flags & TIMESTAMPED ) {
	    db_tsrecs = TRUE;
#ifdef ONE_DB
	    break;
#endif
	 }
#endif
      }
#endif
      /* adjust field table entries */
      for (key_count = 0, i = ORIGIN(fd_offset), 
	      fld_ptr = &field_table[ORIGIN(fd_offset)];
	   i < ORIGIN(fd_offset) + DB_REF(Size_fd);
	   ++i, ++fld_ptr) {
#ifndef	 ONE_DB
	 fld_ptr->fd_rec += curr_db_table->rt_offset;
#endif
	 if ( fld_ptr->fd_key != NOKEY ) {
	    fld_ptr->fd_keyno += key_offset;
	    ++key_count;
#ifndef	 ONE_DB
	    fld_ptr->fd_keyfile += curr_db_table->ft_offset;
	    if ( fld_ptr->fd_type == 'k' )
	       fld_ptr->fd_ptr += curr_db_table->kt_offset;
#endif
	 }
      }
      key_offset += key_count;

#if   DB_ENABLE | TS_ENABLE
      /* adjust set table entries */
      for (i = ORIGIN(st_offset), set_ptr = &set_table[ORIGIN(st_offset)];
	   i < ORIGIN(st_offset) + DB_REF(Size_st);
	   ++i, ++set_ptr) {
#ifndef	 ONE_DB
	 set_ptr->st_own_rt += curr_db_table->rt_offset;
	 set_ptr->st_members += curr_db_table->mt_offset;
#endif
#ifndef	 NO_TIMESTAMP
	 if ( set_ptr->st_flags & TIMESTAMPED ) {
	    db_tssets = TRUE;
#ifdef ONE_DB
	    break;
#endif
	 }
#endif
      }
#endif

#ifndef	 ONE_DB
      /* adjust member table entries */
      for (i = curr_db_table->mt_offset, 
	      mem_ptr = &member_table[curr_db_table->mt_offset];
	   i < curr_db_table->mt_offset + curr_db_table->Size_mt;
	   ++i, ++mem_ptr) {
	 mem_ptr->mt_record += curr_db_table->rt_offset;
	 mem_ptr->mt_sort_fld += curr_db_table->srt_offset;
      }

      /* adjust sort table entries */
      for (i = curr_db_table->srt_offset, 
	      srt_ptr = &sort_table[curr_db_table->srt_offset];
	   i < curr_db_table->srt_offset + curr_db_table->Size_srt;
	   ++i, ++srt_ptr) {
	 srt_ptr->se_fld += curr_db_table->fd_offset;
	 srt_ptr->se_set += curr_db_table->st_offset;
      }

      /* adjust key table entries */
      for (i = curr_db_table->kt_offset, 
	      key_ptr = &key_table[curr_db_table->kt_offset];
	   i < curr_db_table->kt_offset + curr_db_table->Size_kt;
	   ++i, ++key_ptr) {
	 key_ptr->kt_key += curr_db_table->fd_offset;
	 key_ptr->kt_field += curr_db_table->fd_offset;
      }
   }  /* end loop for each database */
#endif
   initcurr();
   return( db_status );
}
Пример #9
0
  bool FileRecord::open(bool create) {
    int oflags = 0;
    int eflags = DB_INIT_CDB | DB_INIT_MPOOL;
    if(create) {
      oflags |= DB_CREATE;
      eflags |= DB_CREATE;
    };
    int mode = S_IRUSR|S_IWUSR;

    db_env_ = new DbEnv(DB_CXX_NO_EXCEPTIONS);
    if(!dberr("Error opening database environment",
          db_env_->open(basepath_.c_str(),eflags,mode))) {
      delete db_env_; db_env_ = NULL;
      db_env_clean(basepath_);
      db_env_ = new DbEnv(DB_CXX_NO_EXCEPTIONS);
      if(!dberr("Error opening database environment",
            db_env_->open(basepath_.c_str(),eflags,mode))) {
        return false;
      };
    };
    dberr("Error setting database environment flags",
          db_env_->set_flags(DB_CDB_ALLDB,1));

    std::string dbpath = FR_DB_NAME;
    if(!verify()) return false;
    // db_link
    //    |---db_lock
    //    \---db_locked
    db_rec_ = new Db(db_env_,DB_CXX_NO_EXCEPTIONS);
    db_lock_ = new Db(db_env_,DB_CXX_NO_EXCEPTIONS);
    db_locked_ = new Db(db_env_,DB_CXX_NO_EXCEPTIONS);
    db_link_ = new Db(db_env_,DB_CXX_NO_EXCEPTIONS);
    if(!dberr("Error setting flag DB_DUPSORT",db_lock_->set_flags(DB_DUPSORT))) return false;
    if(!dberr("Error setting flag DB_DUPSORT",db_locked_->set_flags(DB_DUPSORT))) return false;
    if(!dberr("Error associating databases",db_link_->associate(NULL,db_lock_,&locked_callback,0))) return false;
    if(!dberr("Error associating databases",db_link_->associate(NULL,db_locked_,&lock_callback,0))) return false;
    if(!dberr("Error opening database 'meta'",
          db_rec_->open(NULL,dbpath.c_str(),   "meta",  DB_BTREE,oflags,mode))) return false;
    if(!dberr("Error opening database 'link'",
          db_link_->open(NULL,dbpath.c_str(),  "link",  DB_RECNO,oflags,mode))) return false;
    if(!dberr("Error opening database 'lock'",
          db_lock_->open(NULL,dbpath.c_str(),  "lock",  DB_BTREE,oflags,mode))) return false;
    if(!dberr("Error opening database 'locked'",
          db_locked_->open(NULL,dbpath.c_str(),"locked",DB_BTREE,oflags,mode))) return false;
    return true;
  }
Пример #10
0
int
main(int argc, char *argv[])
{
	extern int optind;
	extern char *optarg;
	enum S command, state;
	DB *dbp;
	DBT data, key, keydata;
	size_t len;
	int ch, oflags, sflag;
	char *fname, *infoarg, *p, *t, buf[8 * 1024];

	infoarg = NULL;
	fname = NULL;
	oflags = O_CREAT | O_RDWR;
	sflag = 0;
	while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1)
		switch (ch) {
		case 'f':
			fname = optarg;
			break;
		case 'i':
			infoarg = optarg;
			break;
		case 'l':
			oflags |= DB_LOCK;
			break;
		case 'o':
			if ((ofd = open(optarg,
			    O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
				dberr("%s: %s", optarg, strerror(errno));
			break;
		case 's':
			sflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	/* Set the type. */
	type = dbtype(*argv++);

	/* Open the descriptor file. */
        if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
	    dberr("%s: %s", *argv, strerror(errno));

	/* Set up the db structure as necessary. */
	if (infoarg == NULL)
		infop = NULL;
	else
		for (p = strtok(infoarg, ",\t "); p != NULL;
		    p = strtok(0, ",\t "))
			if (*p != '\0')
				infop = setinfo(type, p);

	/*
	 * Open the DB.  Delete any preexisting copy, you almost never
	 * want it around, and it often screws up tests.
	 */
	if (fname == NULL) {
		p = getenv("TMPDIR");
		if (p == NULL)
			p = "/var/tmp";
		(void)snprintf(buf, sizeof buf, "%s/__dbtest", p);
		fname = buf;
		(void)unlink(buf);
	} else  if (!sflag)
		(void)unlink(fname);

	if ((dbp = dbopen(fname,
	    oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
		dberr("dbopen: %s", strerror(errno));
	XXdbp = dbp;

	state = COMMAND;
	for (lineno = 1;
	    (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
		/* Delete the newline, displaying the key/data is easier. */
		if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
			*t = '\0';
		if ((len = strlen(buf)) == 0 || isspace((unsigned char)*p) || *p == '#')
			continue;

		/* Convenient gdb break point. */
		if (XXlineno == lineno)
			XXlineno = 1;
		switch (*p) {
		case 'c':			/* compare */
			if (state != COMMAND)
				dberr("line %lu: not expecting command",
				    lineno);
			state = KEY;
			command = COMPARE;
			break;
		case 'e':			/* echo */
			if (state != COMMAND)
				dberr("line %lu: not expecting command",
				    lineno);
			/* Don't display the newline, if CR at EOL. */
			if (p[len - 2] == '\r')
				--len;
			if (write(ofd, p + 1, len - 1) != len - 1 ||
			    write(ofd, "\n", 1) != 1)
				dberr("write: %s", strerror(errno));
			break;
		case 'g':			/* get */
			if (state != COMMAND)
				dberr("line %lu: not expecting command",
				    lineno);
			state = KEY;
			command = GET;
			break;
		case 'p':			/* put */
			if (state != COMMAND)
				dberr("line %lu: not expecting command",
				    lineno);
			state = KEY;
			command = PUT;
			break;
		case 'r':			/* remove */
			if (state != COMMAND)
				dberr("line %lu: not expecting command",
				    lineno);
                        if (flags == R_CURSOR) {
				rem(dbp, &key);
				state = COMMAND;
                        } else {
				state = KEY;
				command = REMOVE;
			}
			break;
		case 'S':			/* sync */
			if (state != COMMAND)
				dberr("line %lu: not expecting command",
				    lineno);
			synk(dbp);
			state = COMMAND;
			break;
		case 's':			/* seq */
			if (state != COMMAND)
				dberr("line %lu: not expecting command",
				    lineno);
			if (flags == R_CURSOR) {
				state = KEY;
				command = SEQ;
			} else
				seq(dbp, &key);
			break;
		case 'f':
			flags = setflags(p + 1);
			break;
		case 'D':			/* data file */
			if (state != DATA)
				dberr("line %lu: not expecting data", lineno);
			data.data = rfile(p + 1, &data.size);
			goto ldata;
		case 'd':			/* data */
			if (state != DATA)
				dberr("line %lu: not expecting data", lineno);
			data.data = xmalloc(p + 1, len - 1);
			data.size = len - 1;
ldata:			switch (command) {
			case COMPARE:
				compare(&keydata, &data);
				break;
			case PUT:
				put(dbp, &key, &data);
				break;
			default:
				dberr("line %lu: command doesn't take data",
				    lineno);
			}
			if (type != DB_RECNO)
				free(key.data);
			free(data.data);
			state = COMMAND;
			break;
		case 'K':			/* key file */
			if (state != KEY)
				dberr("line %lu: not expecting a key", lineno);
			if (type == DB_RECNO)
				dberr("line %lu: 'K' not available for recno",
				    lineno);
			key.data = rfile(p + 1, &key.size);
			goto lkey;
		case 'k':			/* key */
			if (state != KEY)
				dberr("line %lu: not expecting a key", lineno);
			if (type == DB_RECNO) {
				static recno_t recno;
				recno = atoi(p + 1);
				key.data = &recno;
				key.size = sizeof(recno);
			} else {
				key.data = xmalloc(p + 1, len - 1);
				key.size = len - 1;
			}
lkey:			switch (command) {
			case COMPARE:
				getdata(dbp, &key, &keydata);
				state = DATA;
				break;
			case GET:
				get(dbp, &key);
				if (type != DB_RECNO)
					free(key.data);
				state = COMMAND;
				break;
			case PUT:
				state = DATA;
				break;
			case REMOVE:
				rem(dbp, &key);
				if ((type != DB_RECNO) && (flags != R_CURSOR))
					free(key.data);
				state = COMMAND;
				break;
			case SEQ:
				seq(dbp, &key);
				if ((type != DB_RECNO) && (flags != R_CURSOR))
					free(key.data);
				state = COMMAND;
				break;
			default:
				dberr("line %lu: command doesn't take a key",
				    lineno);
			}
			break;
		case 'o':
			dump(dbp, p[1] == 'r');
			break;
		default:
			dberr("line %lu: %s: unknown command character",
			    lineno, p);
		}
	}
#ifdef STATISTICS
	/*
	 * -l must be used (DB_LOCK must be set) for this to be
	 * used, otherwise a page will be locked and it will fail.
	 */
	if (type == DB_BTREE && oflags & DB_LOCK)
		__bt_stat(dbp);
#endif
	if (dbp->close(dbp))
		dberr("db->close: %s", strerror(errno));
	(void)close(ofd);
	exit(0);
}