00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include<Database.h>
00017 #include<DatabaseManager.h>
00018 #include<DatabaseManagerImpl.h>
00019 #include<os.h>
00020 #include<Table.h>
00021 #include<TableImpl.h>
00022 #include<Transaction.h>
00023 #include<CatalogTables.h>
00024 #include<Index.h>
00025 #include<Lock.h>
00026 #include<Debug.h>
00027 #include<Config.h>
00028 #include<Process.h>
00029
00030
00031 DatabaseManagerImpl::~DatabaseManagerImpl()
00032 {
00033
00034 delete tMgr_;
00035 delete lMgr_;
00036 }
00037
00038 void DatabaseManagerImpl::createLockManager()
00039 {
00040 lMgr_ = new LockManager(systemDatabase_);
00041 return;
00042 }
00043
00044 void DatabaseManagerImpl::createTransactionManager()
00045 {
00046
00047 tMgr_ = new TransactionManager();
00048 tMgr_->setFirstTrans(systemDatabase_->getSystemDatabaseTrans(0));
00049 return;
00050 }
00051 void DatabaseManagerImpl::setProcSlot()
00052 {
00053 systemDatabase_->setProcSlot(procSlot);
00054 db_->setProcSlot(procSlot);
00055 }
00056 DbRetVal DatabaseManagerImpl::openSystemDatabase()
00057 {
00058 DbRetVal rv = openDatabase(SYSTEMDB);
00059 if (rv != OK) return rv;
00060 systemDatabase_ = db_;
00061 db_ = NULL;
00062 printDebug(DM_Database, "Opened system database");
00063 logFinest(logger, "Opened system database");
00064 return OK;
00065 }
00066
00067 DbRetVal DatabaseManagerImpl::closeSystemDatabase()
00068 {
00069 Database *db = db_;
00070
00071
00072 db_ = systemDatabase_;
00073 closeDatabase();
00074 db_ = db;
00075 printDebug(DM_Database, "Closed system database");
00076 logFinest(logger, "Closed System database");
00077 return OK;
00078 }
00079
00084 DbRetVal DatabaseManagerImpl::createDatabase(const char *name, size_t size)
00085 {
00086 if (NULL != db_ )
00087 {
00088 printError(ErrAlready, "Database is already created");
00089 return ErrAlready;
00090 }
00091 caddr_t rtnAddr = (caddr_t) NULL;
00092 shared_memory_id shm_id = 0;
00093
00094 char *startaddr = (char*)Conf::config.getMapAddress();
00095 shared_memory_key key = 0;
00096 if (0 == strcmp(name, SYSTEMDB))
00097 {
00098
00099 key = Conf::config.getSysDbKey();
00100 }
00101 else
00102 {
00103 startaddr = startaddr + Conf::config.getMaxSysDbSize();
00104 key = Conf::config.getUserDbKey();
00105 }
00106 shm_id = os::shm_create(key, size, 0666);
00107 if (-1 == shm_id)
00108 {
00109 if (errno == EEXIST) {
00110 printError(ErrOS, "Shared Memory already exists");
00111 }
00112 printError(ErrOS, "Shared memory create failed");
00113 return ErrOS;
00114 }
00115
00116 void *shm_ptr = os::shm_attach(shm_id, startaddr, SHM_RND);
00117 rtnAddr = (caddr_t) shm_ptr;
00118 if (rtnAddr < 0 || shm_ptr == (char*)0xffffffff)
00119 {
00120 printError(ErrOS, "Shared memory attach returned -ve value %d", rtnAddr);
00121 return ErrOS;
00122 }
00123 memset(shm_ptr, 0, size );
00124 db_ = new Database();
00125 printDebug(DM_Database, "Creating database:%s",name);
00126
00127
00128 db_->setMetaDataPtr((DatabaseMetaData*)rtnAddr);
00129 db_->setDatabaseID(1);
00130 db_->setName(name);
00131 db_->setMaxSize(size);
00132 db_->setNoOfChunks(0);
00133 db_->initAllocDatabaseMutex();
00134 db_->initTransTableMutex();
00135 db_->initDatabaseMutex();
00136 db_->initProcessTableMutex();
00137
00138
00139 size_t offset = os::alignLong(sizeof (DatabaseMetaData));
00140
00141 if (0 == strcmp(name, SYSTEMDB))
00142 {
00143 offset = offset + os::alignLong( MAX_CHUNKS * sizeof (Chunk));
00144 offset = offset + os::alignLong( Conf::config.getMaxProcs() * sizeof(Transaction));
00145 offset = offset + os::alignLong( Conf::config.getMaxProcs() * sizeof(ThreadInfo));
00146 }
00147 int multiple = os::floor(offset / PAGE_SIZE);
00148 char *curPage = (((char*)rtnAddr) + ((multiple + 1) * PAGE_SIZE));
00149
00150 db_->setCurrentPage(curPage);
00151 db_->setFirstPage(curPage);
00152
00153 if (0 == strcmp(name, SYSTEMDB)) return OK;
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 logFinest(logger, "Created database %s" , name);
00167
00168 return OK;
00169 }
00175 DbRetVal DatabaseManagerImpl::deleteDatabase(const char *name)
00176 {
00177 shared_memory_id shm_id = 0;
00178 if (0 == strcmp(name, SYSTEMDB))
00179 {
00180 shm_id = os::shm_open(Conf::config.getSysDbKey(), 100, 0666);
00181 os::shmctl(shm_id, IPC_RMID);
00182 delete systemDatabase_;
00183 systemDatabase_ = NULL;
00184 } else {
00185 shm_id = os::shm_open(Conf::config.getUserDbKey(), 100, 0666);
00186 os::shmctl(shm_id, IPC_RMID);
00187 delete db_;
00188 db_ = NULL;
00189 }
00190 logFinest(logger, "Deleted database %s" , name);
00191 return OK;
00192 }
00193
00198 DbRetVal DatabaseManagerImpl::openDatabase(const char *name)
00199 {
00200 long size = Conf::config.getMaxSysDbSize();
00201 char *startaddr = (char*)Conf::config.getMapAddress();
00202 if (0 == strcmp(name , SYSTEMDB))
00203 {
00204 if (NULL !=systemDatabase_)
00205 {
00206 printError(ErrAlready, "System Database already open");
00207 return ErrAlready;
00208 }
00209 }
00210 else
00211 {
00212 if (NULL ==systemDatabase_)
00213 {
00214 printError(ErrNotOpen, "System Database not open");
00215 return ErrNotOpen;
00216 }
00217 size = Conf::config.getMaxDbSize();
00218 startaddr = startaddr + Conf::config.getMaxSysDbSize();
00219 }
00220 if (NULL != db_)
00221 {
00222 printError(ErrAlready, "User Database already open");
00223 return ErrAlready;
00224 }
00225
00226 caddr_t rtnAddr = (caddr_t) NULL;
00227
00228 shared_memory_id shm_id = 0;
00229 shared_memory_key key = 0;
00230
00231 if (0 == strcmp(name, SYSTEMDB))
00232 key = Conf::config.getSysDbKey();
00233 else
00234 key = Conf::config.getUserDbKey();
00235
00236
00237 int ret = ProcessManager::mutex.getLock(-1, false);
00238
00239
00240 if (ret != 0)
00241 {
00242 printError(ErrSysInternal, "Another thread calling open:Wait and then Retry\n");
00243 return ErrSysInternal;
00244 }
00245 void *shm_ptr = NULL;
00246 bool firstThread = false;
00247
00248 if (ProcessManager::noThreads == 0 && 0 == strcmp(name, SYSTEMDB)
00249 || ProcessManager::noThreads == 1 && 0 != strcmp(name, SYSTEMDB) ) {
00250 shm_id = os::shm_open(key, size, 0666);
00251 if (shm_id == -1 )
00252 {
00253 printError(ErrOS, "Shared memory open failed");
00254 ProcessManager::mutex.releaseLock(-1, false);
00255 return ErrOS;
00256 }
00257 shm_ptr = os::shm_attach(shm_id, startaddr, SHM_RND);
00258 if (0 == strcmp(name, SYSTEMDB))
00259 {
00260 firstThread = true;
00261 ProcessManager::sysAddr = (char*) shm_ptr;
00262 }
00263 else
00264 {
00265 ProcessManager::usrAddr = (char*) shm_ptr;
00266 }
00267 } else {
00268 if (0 == strcmp(name, SYSTEMDB))
00269 shm_ptr = ProcessManager::sysAddr;
00270 else
00271 shm_ptr = ProcessManager::usrAddr;
00272 }
00273 ProcessManager::mutex.releaseLock(-1, false);
00274
00275
00276 rtnAddr = (caddr_t) shm_ptr;
00277
00278 if (rtnAddr < 0 || shm_ptr == (char*)0xffffffff)
00279 {
00280 printError(ErrOS, "Shared memory attach returned -ve value %x %d", shm_ptr, errno);
00281 return ErrOS;
00282 }
00283 db_ = new Database();
00284 db_->setMetaDataPtr((DatabaseMetaData*)rtnAddr);
00285
00286 if (firstThread) ProcessManager::systemDatabase = db_;
00287
00288 printDebug(DM_Database, "Opening database: %s", name);
00289 logFinest(logger, "Opened database %s" , name);
00290 return OK;
00291 }
00292
00293 DbRetVal DatabaseManagerImpl::closeDatabase()
00294 {
00295
00296 if (NULL == db_)
00297 {
00298
00299 return OK;
00300 }
00301 printDebug(DM_Database, "Closing database: %s",(char*)db_->getName());
00302
00303 int ret = ProcessManager::mutex.getLock(-1, false);
00304
00305
00306 if (ret == 0) {
00307
00308 if (ProcessManager::noThreads == 0 && 0 == strcmp((char*)db_->getName(), SYSTEMDB)
00309 || ProcessManager::noThreads == 1 && 0 != strcmp((char*)db_->getName(), SYSTEMDB) ) {
00310 os::shm_detach((char*)db_->getMetaDataPtr());
00311 }
00312 }
00313 ProcessManager::mutex.releaseLock(-1, false);
00314 logFinest(logger, "Closed database");
00315 delete db_;
00316 db_ = NULL;
00317 return OK;
00318 }
00319
00320 Chunk* DatabaseManagerImpl::createUserChunk(size_t size)
00321 {
00322
00323 Chunk *chunk = getSystemTableChunk(UserChunkTableId);
00324 DbRetVal rv = OK;
00325 void *ptr = chunk->allocate(systemDatabase_, &rv);
00326 if (NULL == ptr)
00327 {
00328 printError(rv, "Allocation failed for User chunk catalog table");
00329 return NULL;
00330 }
00331 Chunk *chunkInfo = (Chunk*)ptr;
00332 chunkInfo->initMutex();
00333 if (0 != size) chunkInfo->setSize(size);
00334 if (chunkInfo->allocSize_ > PAGE_SIZE)
00335 chunkInfo->curPage_ = db_->getFreePage(chunkInfo->allocSize_);
00336 else
00337 chunkInfo->curPage_ = db_->getFreePage();
00338 if ( NULL == chunkInfo->curPage_)
00339 {
00340 chunkInfo->destroyMutex();
00341 chunk->free(db_, ptr);
00342 printError(ErrNoMemory, "Database full: No space to allocate from database");
00343 return NULL;
00344 }
00345 PageInfo* firstPageInfo = ((PageInfo*)chunkInfo->curPage_);
00346 if (chunkInfo->allocSize_ > PAGE_SIZE)
00347 {
00348 int multiple = os::floor(chunkInfo->allocSize_ / PAGE_SIZE);
00349 int offset = ((multiple + 1) * PAGE_SIZE);
00350 firstPageInfo->setPageAsUsed(offset);
00351 }
00352 else
00353 {
00354 firstPageInfo->setPageAsUsed(chunkInfo->allocSize_);
00355 char *data = ((char*)firstPageInfo) + sizeof(PageInfo);
00356 *(int*)data =0;
00357 }
00358 if (0 == size)
00359 {
00360 VarSizeInfo *varInfo = (VarSizeInfo*)(((char*)firstPageInfo) + sizeof(PageInfo));
00361 varInfo->isUsed_ = 0;
00362 varInfo->size_ = PAGE_SIZE - sizeof(PageInfo) - sizeof(VarSizeInfo);
00363
00364 }
00365 chunkInfo->firstPage_ = chunkInfo->curPage_;
00366
00367 if (0 == size)
00368 chunkInfo->setAllocType(VariableSizeAllocator);
00369 else
00370 chunkInfo->setAllocType(FixedSizeAllocator);
00371
00372
00373 chunkInfo->setChunkID(-1);
00374 db_->incrementChunk();
00375 printDebug(DM_Database, "Creating new User chunk chunkID:%d size: %d firstPage:%x",
00376 -1, chunkInfo->allocSize_, firstPageInfo);
00377
00378 return chunkInfo;
00379 }
00380
00381
00382 DbRetVal DatabaseManagerImpl::deleteUserChunk(Chunk *chunk)
00383 {
00384
00385 Page *page = chunk->firstPage_;
00386 PageInfo* pageInfo = ((PageInfo*)page);
00387
00388
00389 while( pageInfo->nextPage_ != NULL)
00390 {
00391 PageInfo *prev = pageInfo;
00392 pageInfo = (PageInfo*)(pageInfo->nextPage_);
00393
00394
00395 if(NULL == pageInfo->nextPageAfterMerge_)
00396 os::memset(prev, 0, PAGE_SIZE);
00397 else
00398 {
00399 int size = (char*) pageInfo->nextPageAfterMerge_ - (char*) pageInfo;
00400 os::memset(prev, 0, size);
00401 }
00402 printDebug(DM_Database,"deleting user chunk:%x clearing page %x",chunk, prev);
00403 }
00404
00405
00406 if(NULL == pageInfo->nextPageAfterMerge_)
00407 os::memset(pageInfo, 0, PAGE_SIZE);
00408 else
00409 {
00410 int size = (char*) pageInfo->nextPageAfterMerge_ - (char*) pageInfo;
00411 os::memset(pageInfo, 0, size);
00412 }
00413 printDebug(DM_Database,"deleting user chunk:%x clearing page %x",chunk, pageInfo);
00414 chunk->chunkID_ = -1;
00415 chunk->allocSize_ = 0;
00416 chunk->curPage_ = NULL;
00417 chunk->firstPage_ = NULL;
00418 chunk->destroyMutex();
00419 db_->decrementChunk();
00420 printDebug(DM_Database,"deleting user chunk:%x",chunk);
00421 return OK;
00422 }
00423
00424
00425
00426 DbRetVal DatabaseManagerImpl::createTable(const char *name, TableDef &def)
00427 {
00428 DbRetVal rv = OK;
00429 int fldCount = def.getFieldCount();
00430
00431
00432
00433
00434 int addSize = 0;
00435 if (fldCount < 31) addSize = 4; else addSize = os::align(fldCount);
00436 size_t sizeofTuple = os::align(def.getTupleSize())+addSize;
00437
00438 rv = systemDatabase_->getDatabaseMutex();
00439 if (OK != rv ) {
00440 printError(rv, "Unable to get Database mutex");
00441 return rv;
00442 }
00443
00444 void *tptr =NULL;
00445 void *chunk = NULL;
00446
00447
00448 CatalogTableTABLE cTable(systemDatabase_);
00449 cTable.getChunkAndTblPtr(name, chunk, tptr);
00450 if (NULL != tptr)
00451 {
00452 systemDatabase_->releaseDatabaseMutex();
00453 printError(ErrAlready, "Table %s already exists", name);
00454 return ErrAlready;
00455 }
00456
00457
00458 Chunk *ptr = createUserChunk(sizeofTuple);
00459 if (NULL == ptr)
00460 {
00461 systemDatabase_->releaseDatabaseMutex();
00462 printError(ErrNoResource, "Unable to create user chunk");
00463 return ErrNoResource;
00464 }
00465 printDebug(DM_Database,"Created UserChunk:%x", ptr);
00466
00467
00468 int tblID = ((Chunk*)ptr)->getChunkID();
00469 rv = cTable.insert(name, tblID, sizeofTuple,
00470 def.getFieldCount(), ptr, tptr);
00471 if (OK != rv)
00472 {
00473 deleteUserChunk(ptr);
00474 systemDatabase_->releaseDatabaseMutex();
00475 printError(ErrSysInternal, "Unable to update catalog table TABLE");
00476 return ErrSysInternal;
00477 }
00478 printDebug(DM_Database,"Inserted into TABLE:%s",name);
00479
00480 FieldIterator iter = def.getFieldIterator();
00481 CatalogTableFIELD cField(systemDatabase_);
00482 rv = cField.insert(iter, tblID ,tptr);
00483 if (OK != rv)
00484 {
00485 deleteUserChunk(ptr);
00486 void *cptr, *ttptr;
00487 cTable.remove(name, cptr, ttptr);
00488 systemDatabase_->releaseDatabaseMutex();
00489 printError(ErrSysInternal, "Unable to update catalog table FIELD");
00490 return ErrSysInternal;
00491 }
00492 printDebug(DM_Database,"Inserted into FIELD:%s",name);
00493 systemDatabase_->releaseDatabaseMutex();
00494 printDebug(DM_Database,"Table Created:%s",name);
00495 logFinest(logger, "Table Created %s" , name);
00496 return OK;
00497 }
00498
00499
00500
00501
00502
00503
00504 DbRetVal DatabaseManagerImpl::dropTable(const char *name)
00505 {
00506 void *chunk = NULL;
00507 void *tptr =NULL;
00508 DbRetVal rv = systemDatabase_->getDatabaseMutex();
00509 if (OK != rv) {
00510 printError(ErrSysInternal, "Unable to get database mutex");
00511 return ErrSysInternal;
00512 }
00513
00514
00515 CatalogTableTABLE cTable(systemDatabase_);
00516 rv = cTable.getChunkAndTblPtr(name, chunk, tptr);
00517 if (OK != rv) {
00518 systemDatabase_->releaseDatabaseMutex();
00519 printError(ErrSysInternal, "Table %s does not exist", name);
00520 return ErrSysInternal;
00521 }
00522 rv = lMgr_->getExclusiveLock(chunk, NULL);
00523 if (rv !=OK)
00524 {
00525 systemDatabase_->releaseDatabaseMutex();
00526 printError(ErrLockTimeOut, "Unable to acquire exclusive lock on the table\n");
00527 return rv;
00528 }
00529
00530 rv = cTable.remove(name, chunk, tptr);
00531 if (OK != rv) {
00532 systemDatabase_->releaseDatabaseMutex();
00533 printError(ErrSysInternal, "Unable to update catalog table TABLE");
00534 return ErrSysInternal;
00535 }
00536 printDebug(DM_Database,"Deleted from TABLE:%s",name);
00537
00538
00539 CatalogTableFIELD cField(systemDatabase_);
00540 rv = cField.remove(tptr);
00541 if (OK != rv) {
00542 systemDatabase_->releaseDatabaseMutex();
00543 printError(ErrSysInternal, "Unable to update catalog table FIELD");
00544 return ErrSysInternal;
00545 }
00546 printDebug(DM_Database,"Deleted from FIELD:%s",name);
00547
00548 rv = deleteUserChunk((Chunk*)chunk);
00549 if (OK != rv) {
00550 systemDatabase_->releaseDatabaseMutex();
00551 printError(rv, "Unable to delete the chunk");
00552 return rv;
00553 }
00554 printDebug(DM_Database,"Deleted UserChunk:%x", chunk);
00555
00556
00557 CatalogTableINDEX cIndex(systemDatabase_);
00558 int noIndexes = cIndex.getNumIndexes(tptr);
00559 for (int i =1 ; i<= noIndexes; i++) {
00560 char *idxName = cIndex.getIndexName(tptr, 1);
00561 dropIndexInt(idxName, false);
00562 }
00563 Chunk *chunkNode = systemDatabase_->getSystemDatabaseChunk(UserChunkTableId);
00564 chunkNode->free(systemDatabase_, (Chunk *) chunk);
00565 systemDatabase_->releaseDatabaseMutex();
00566 printDebug(DM_Database, "Deleted Table %s" , name);
00567 logFinest(logger, "Deleted Table %s" , name);
00568 rv = lMgr_->releaseLock(chunk);
00569 if (rv !=OK)
00570 {
00571 printError(ErrLockTimeOut, "Unable to release exclusive lock on the table\n");
00572 return rv;
00573 }
00574 return OK;
00575 }
00576
00577
00578 Table* DatabaseManagerImpl::openTable(const char *name)
00579 {
00580 DbRetVal ret = OK;
00581
00582
00583 TableImpl *table = new TableImpl();
00584 table->setDB(db_);
00585 table->setSystemDB(systemDatabase_);
00586 table->setLockManager(lMgr_);
00587 table->setTrans(ProcessManager::getThreadTransAddr(systemDatabase_->procSlot));
00588
00589
00590 void *chunk = NULL;
00591
00592
00593 void *tptr =NULL;
00594
00595
00596
00597
00598
00599 DbRetVal rv = systemDatabase_->getDatabaseMutex();
00600 if (OK != rv) {
00601 printError(ErrSysInternal, "Unable to get database mutex");
00602 delete table;
00603 return NULL;
00604 }
00605 CatalogTableTABLE cTable(systemDatabase_);
00606 ret = cTable.getChunkAndTblPtr(name, chunk, tptr);
00607 if ( OK != ret)
00608 {
00609 systemDatabase_->releaseDatabaseMutex();
00610 delete table;
00611 printError(ErrNotExists, "Table not exists %s", name);
00612 return NULL;
00613 }
00614 TABLE *tTuple = (TABLE*)tptr;
00615 table->setTableInfo(tTuple->tblName_, tTuple->tblID_, tTuple->length_,
00616 tTuple->numFlds_, tTuple->numIndexes_, tTuple->chunkPtr_);
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 if (tTuple->numFlds_ < 31)
00628 {
00629 table->isIntUsedForNULL = true;
00630 table->iNullInfo = 0;
00631 table->iNotNullInfo =0;
00632 }
00633 else
00634 {
00635 table->isIntUsedForNULL = false;
00636 int noFields = os::align(tTuple->numFlds_);
00637 table->cNullInfo = (char*) malloc(noFields);
00638 table->cNotNullInfo = (char*) malloc(noFields);
00639 for (int i =0 ; i < noFields; i++) table->cNullInfo[i] =0;
00640 for (int i =0 ; i < noFields; i++) table->cNotNullInfo[i] =0;
00641
00642 }
00643
00644
00645 CatalogTableFIELD cField(systemDatabase_);
00646 cField.getFieldInfo(tptr, table->fldList_);
00647
00648
00649 FieldIterator fIter = table->fldList_.getIterator();
00650 int fldpos=1;
00651 while (fIter.hasElement())
00652 {
00653 FieldDef def = fIter.nextElement();
00654 if (table->isIntUsedForNULL) {
00655 if (def.isNull_) SETBIT(table->iNotNullInfo, fldpos);
00656 }
00657 else {
00658 if (def.isNull_) table->cNotNullInfo[fldpos-1] = 1;
00659 }
00660 fldpos++;
00661 }
00662
00663
00664
00665 CatalogTableINDEX cIndex(systemDatabase_);
00666 table->numIndexes_ = cIndex.getNumIndexes(tptr);
00667 if (table->numIndexes_) {
00668 table->indexPtr_ = new char*[table->numIndexes_];
00669 table->idxInfo = new IndexInfo*[table->numIndexes_];
00670 }
00671 else
00672 {
00673 table->indexPtr_ = NULL;
00674 }
00675 cIndex.getIndexPtrs(tptr, table->indexPtr_);
00676 for (int i =0 ; i < table->numIndexes_; i++ )
00677 {
00678 SingleFieldHashIndexInfo *hIdxInfo = new SingleFieldHashIndexInfo();
00679 CatalogTableINDEXFIELD cIndexField(systemDatabase_);
00680 cIndexField.getFieldNameAndType(table->indexPtr_[i], hIdxInfo->fldName,
00681 hIdxInfo->type);
00682 ChunkIterator citer = CatalogTableINDEX::getIterator(table->indexPtr_[i]);
00683 hIdxInfo->noOfBuckets = CatalogTableINDEX::getNoOfBuckets(table->indexPtr_[i]);
00684 hIdxInfo->isUnique = CatalogTableINDEX::getUnique(table->indexPtr_[i]);
00685 hIdxInfo->buckets = (Bucket*)citer.nextElement();
00686 hIdxInfo->offset = table->fldList_.getFieldOffset(hIdxInfo->fldName);
00687 hIdxInfo->length = table->fldList_.getFieldLength(hIdxInfo->fldName);
00688 table->idxInfo[i] = (IndexInfo*) hIdxInfo;
00689 }
00690 systemDatabase_->releaseDatabaseMutex();
00691
00692 printDebug(DM_Database,"Opening table handle name:%s chunk:%x numIndex:%d",
00693 name, chunk, table->numIndexes_);
00694 logFinest(logger, "Opening Table %s" , name);
00695
00696
00697 return table;
00698 }
00699
00700
00701
00702 List DatabaseManagerImpl::getAllTableNames()
00703 {
00704 DbRetVal ret = OK;
00705
00706 void *tptr =NULL;
00707
00708 DbRetVal rv = systemDatabase_->getDatabaseMutex();
00709 if (OK != rv) {
00710 printError(ErrSysInternal, "Unable to get database mutex");
00711 List tableList;
00712 return tableList;
00713 }
00714 CatalogTableTABLE cTable(systemDatabase_);
00715 List tableList = cTable.getTableList();
00716 systemDatabase_->releaseDatabaseMutex();
00717 return tableList;
00718 }
00719
00720
00721
00722
00723
00724 void DatabaseManagerImpl::closeTable(Table *table)
00725 {
00726 printDebug(DM_Database,"Closing table handle: %x", table);
00727 if (NULL == table) return;
00728
00729 delete table;
00730 logFinest(logger, "Closing Table");
00731 }
00732
00733 DbRetVal DatabaseManagerImpl::createIndex(const char *indName, IndexInitInfo *info)
00734 {
00735 DbRetVal rv = OK;
00736 if (!info->isUnique && info->isPrimary)
00737 {
00738 printError(ErrBadCall, "Primary key cannot be non unique\n");
00739 return ErrBadCall;
00740 }
00741 if (info->indType == hashIndex)
00742 {
00743
00744 HashIndexInitInfo *hInfo = (HashIndexInitInfo*) info;
00745 rv = createHashIndex(indName, info->tableName, info->list, hInfo->bucketSize,
00746 info->isUnique, info->isPrimary);
00747 }
00748 else if (info->indType == treeIndex)
00749 {
00750
00751 printError(ErrNotYet, "Tree Index not supported\n");
00752 return ErrNotYet;
00753 }else {
00754 printError(ErrBadCall, "Index type not supported\n");
00755 return ErrBadCall;
00756 }
00757 return rv;
00758 }
00759
00760
00761
00762
00763
00764 DbRetVal DatabaseManagerImpl::createHashIndex(const char *indName, const char *tblName,
00765 FieldNameList &fldList, int bucketSize, bool isUnique, bool isPrimary)
00766 {
00767
00768 if (bucketSize < 100 || bucketSize > 200000)
00769 {
00770 printError(ErrBadRange, "Index Bucket size %d not in range 100-200000",
00771 bucketSize);
00772 return ErrBadRange;
00773 }
00774 int totFlds = fldList.size();
00775 if (totFlds == 0)
00776 {
00777 printError(ErrBadCall, "No Field name specified");
00778 return ErrBadCall;
00779 }else if (totFlds >1) {
00780 printError(ErrNotYet, "Composite keys not supported");
00781 return ErrNotYet;
00782 }
00783 void *tptr =NULL;
00784 void *chunk = NULL;
00785 DbRetVal rv = systemDatabase_->getDatabaseMutex();
00786 if (OK != rv)
00787 {
00788 printError(ErrSysInternal, "Unable to get database mutex");
00789 return ErrSysInternal;
00790 }
00791
00792
00793 CatalogTableTABLE cTable(systemDatabase_);
00794 cTable.getChunkAndTblPtr(tblName, chunk, tptr);
00795 if (NULL == tptr)
00796 {
00797 systemDatabase_->releaseDatabaseMutex();
00798 printError(ErrNotExists, "Table does not exist %s", tblName);
00799 return ErrNotExists;
00800 }
00801
00802
00803 char **fptr = new char* [totFlds];
00804 CatalogTableFIELD cField(systemDatabase_);
00805 rv = cField.getFieldPtrs(fldList, tptr, fptr);
00806 if (OK != rv)
00807 {
00808 delete[] fptr;
00809 systemDatabase_->releaseDatabaseMutex();
00810
00811
00813
00814
00815
00816
00817 if (rv != ErrBadCall) {
00818 printError(ErrNotExists, "Field does not exist");
00819 return ErrNotExists;
00820 }
00821 }
00822 for (int i=0; i <totFlds; i++)
00823 {
00824 FIELD* fInfo = (FIELD*)fptr[i];
00825 if (fInfo->type_ == typeFloat || fInfo->type_ == typeDouble || fInfo->type_ == typeTimeStamp)
00826 {
00827 printError(ErrBadArg, "HashIndex cannot be created for float or double or timestamp type");
00828 delete[] fptr;
00829 systemDatabase_->releaseDatabaseMutex();
00830 return ErrBadArg;
00831 }
00832 if (!fInfo->isNull_ && isPrimary )
00833 {
00834 printError(ErrBadArg, "Primary Index cannot be created on field without NOTNULL constraint");
00835 delete[] fptr;
00836 systemDatabase_->releaseDatabaseMutex();
00837 return ErrBadArg;
00838 }
00839 }
00840
00841
00842 printDebug(DM_HashIndex, "Creating chunk for storing hash buckets of size %d\n",
00843 bucketSize * sizeof(Bucket));
00844 Chunk* chunkInfo = createUserChunk(bucketSize * sizeof(Bucket));
00845 if (NULL == chunkInfo)
00846 {
00847 delete[] fptr;
00848 systemDatabase_->releaseDatabaseMutex();
00849 printError(ErrSysInternal, "Unable to create chunk");
00850 return ErrSysInternal;
00851 }
00852
00853 void *buckets = chunkInfo->allocate(db_, &rv);
00854 if (NULL == buckets)
00855 {
00856 delete[] fptr;
00857 deleteUserChunk(chunkInfo);
00858 systemDatabase_->releaseDatabaseMutex();
00859 printError(rv, "Unable to allocate memory for bucket");
00860 return rv;
00861 }
00862 Bucket *buck = (Bucket*) buckets;
00863 initHashBuckets(buck, bucketSize);
00864
00865
00866 Chunk* hChunk = createUserChunk(sizeof(HashIndexNode));
00867 if (NULL == hChunk)
00868 {
00869 delete[] fptr;
00870 deleteUserChunk(chunkInfo);
00871 systemDatabase_->releaseDatabaseMutex();
00872 printError(ErrSysInternal, "Unable to create chunk for storing hash index nodes");
00873 return ErrSysInternal;
00874 }
00875
00876
00877
00878 void *tupleptr = NULL;
00879 CatalogTableINDEX cIndex(systemDatabase_);
00880 rv = cIndex.insert(indName, tptr, fldList.size(), isUnique,
00881 chunkInfo, bucketSize, hChunk, tupleptr);
00882 if (OK != rv)
00883 {
00884 delete[] fptr;
00885 deleteUserChunk(hChunk);
00886 deleteUserChunk(chunkInfo);
00887 systemDatabase_->releaseDatabaseMutex();
00888 printError(ErrSysInternal, "Catalog table updation failed in INDEX table");
00889 return ErrSysInternal;
00890 }
00891
00892 CatalogTableINDEXFIELD cIndexField(systemDatabase_);
00893 rv = cIndexField.insert(fldList, tupleptr, tptr, fptr);
00894
00895 if (OK != rv)
00896 {
00897 delete[] fptr;
00898 cIndex.remove(indName, (void *&)chunkInfo, (void *&)hChunk, (void *&)tupleptr);
00899 deleteUserChunk(hChunk);
00900 deleteUserChunk(chunkInfo);
00901 systemDatabase_->releaseDatabaseMutex();
00902 printError(ErrSysInternal, "Catalog table updation failed in INDEXFIELD table");
00903 return ErrSysInternal;
00904 }
00905 delete[] fptr;
00906
00907
00908
00909 systemDatabase_->releaseDatabaseMutex();
00910 printDebug(DM_Database, "Creating Hash Index Name:%s tblname:%s buckets:%x",
00911 indName, tblName, buckets);
00912 logFinest(logger, "Creating HashIndex %s on %s with bucket size %d",
00913 indName, tblName, buckets);
00914 return OK;
00915 }
00916
00917 void DatabaseManagerImpl::initHashBuckets(Bucket *buck, int bucketSize)
00918 {
00919 os::memset((void*)buck, 0, bucketSize * sizeof(Bucket));
00920
00921 for (int i=0; i < bucketSize ; i++)
00922 {
00923 buck[i].mutex_.init("Bucket");
00924 }
00925 return;
00926 }
00927
00928 DbRetVal DatabaseManagerImpl::dropIndex(const char *name)
00929 {
00930 return dropIndexInt(name, true);
00931 }
00932
00933 DbRetVal DatabaseManagerImpl::dropIndexInt(const char *name, bool takeLock)
00934 {
00935 DbRetVal rv = OK;
00936 void *chunk = NULL, *hchunk = NULL;
00937 void *tptr =NULL;
00938 int ret = 0;
00939 if (takeLock) {
00940 rv = systemDatabase_->getDatabaseMutex();
00941 if (OK != rv)
00942 {
00943 printError(ErrSysInternal, "Unable to get database mutex");
00944 return ErrSysInternal;
00945 }
00946 }
00947
00948
00949 CatalogTableINDEX cIndex(systemDatabase_);
00950 rv = cIndex.remove(name, chunk, hchunk, tptr);
00951 if (OK != rv)
00952 {
00953 if (takeLock) systemDatabase_->releaseDatabaseMutex();
00954 printError(ErrSysInternal, "Catalog table updation failed for INDEX table");
00955 return ErrSysInternal;
00956 }
00957 printDebug(DM_Database, "Removing from INDEX %s",name);
00958
00959 CatalogTableINDEXFIELD cIndexField(systemDatabase_);
00960 rv = cIndexField.remove(tptr);
00961 if (OK != rv)
00962 {
00963 if (takeLock) systemDatabase_->releaseDatabaseMutex();
00964 printError(ErrSysInternal, "Catalog table updation failed for INDEX table");
00965 return ErrSysInternal;
00966 }
00967 printDebug(DM_Database, "Removing from INDEXFIELD %s",name);
00968
00969
00970 rv = deleteUserChunk((Chunk*)chunk);
00971 if (OK != rv)
00972 {
00973 if (takeLock) systemDatabase_->releaseDatabaseMutex();
00974 printError(ErrSysInternal, "Unable to delete the index chunk");
00975 return ErrSysInternal;
00976 }
00977
00978 rv = deleteUserChunk((Chunk*)hchunk);
00979 if (OK != rv)
00980 {
00981 if (takeLock) systemDatabase_->releaseDatabaseMutex();
00982 printError(ErrSysInternal, "Unable to delete the index hash node chunk");
00983 return ErrSysInternal;
00984 }
00985 if (takeLock) systemDatabase_->releaseDatabaseMutex();
00986 Chunk *chunkNode = systemDatabase_->getSystemDatabaseChunk(UserChunkTableId);
00987 chunkNode->free(systemDatabase_, (Chunk *) chunk);
00988 chunkNode->free(systemDatabase_, (Chunk *) hchunk);
00989
00990
00991
00992
00993
00994
00995 printDebug(DM_Database, "Dropped hash index %s",name);
00996 logFinest(logger, "Deleted Index %s", name);
00997 return OK;
00998 }
00999 DbRetVal DatabaseManagerImpl::printIndexInfo(char *name)
01000 {
01001 CatalogTableINDEX cIndex(systemDatabase_);
01002 DbRetVal rv = OK;
01003 void *chunk = NULL, *hchunk = NULL;
01004 void *tptr =NULL;
01005 rv = cIndex.get(name, chunk, hchunk, tptr);
01006 if (OK != rv) return rv;
01007 printf("<IndexName> %s </IndexName>\n", name);
01008 printf("<Unique> %d </Unique>\n", CatalogTableINDEX::getUnique(tptr));
01009 Chunk *ch = (Chunk*) chunk;
01010 printf("<HashBucket>\n");
01011 printf(" <TotalPages> %d </TotalPages>\n", ch->totalPages());
01012 printf(" <TotalBuckets> %d </TotalBuckets> \n", CatalogTableINDEX::getNoOfBuckets(tptr));
01013 printf("</HashBucket>\n");
01014
01015 ch = (Chunk*) hchunk;
01016 printf("<IndexNodes>\n");
01017 printf(" <TotalPages> %d </TotalPages>\n", ch->totalPages());
01018 printf(" <TotalNodes> %d </TotalNodes>\n", ch->getTotalDataNodes());
01019 printf("<IndexNodes>\n");
01020 return OK;
01021 }
01022
01023 DbRetVal DatabaseManagerImpl::registerThread()
01024 {
01025 DbRetVal rv = OK;
01026 if (pMgr_ != NULL)
01027 {
01028 printError(ErrAlready, "Process already registered\n");
01029 return ErrAlready;
01030 }
01031 pMgr_ = new ProcessManager();
01032 rv = pMgr_->registerThread();
01033 if (rv ==OK) { procSlot = pMgr_->getProcSlot();
01034 printDebug(DM_Process, "Process registed with slot %d\n", procSlot);
01035 }
01036 return rv;
01037 }
01038
01039 DbRetVal DatabaseManagerImpl::deregisterThread()
01040 {
01041 DbRetVal rv = OK;
01042 if (pMgr_ != NULL)
01043 {
01044 rv = pMgr_->deregisterThread(procSlot);
01045 delete pMgr_;
01046 pMgr_ = NULL;
01047 }
01048 return rv;
01049 }
01050
01051 bool DatabaseManagerImpl::isAnyOneRegistered()
01052 {
01053 if (pMgr_ != NULL) return pMgr_->isAnyOneRegistered();
01054 return true;
01055 }
01056
01057
01058 void DatabaseManagerImpl::printUsageStatistics()
01059 {
01060 pMgr_->printUsageStatistics();
01061 tMgr_->printUsageStatistics();
01062 lMgr_->printUsageStatistics();
01063 }
01064
01065 void DatabaseManagerImpl::printDebugLockInfo()
01066 {
01067 lMgr_->printDebugInfo();
01068 }
01069
01070 void DatabaseManagerImpl::printDebugTransInfo()
01071 {
01072 tMgr_->printDebugInfo(systemDatabase_);
01073 }
01074 void DatabaseManagerImpl::printDebugProcInfo()
01075 {
01076 pMgr_->printDebugInfo();
01077 }
01078 void DatabaseManagerImpl::printDebugChunkInfo()
01079 {
01080 printf("<NotYetImplemented> </NotYetImplemented>\n");
01081 }
01082 ChunkIterator DatabaseManagerImpl::getSystemTableIterator(CatalogTableID id)
01083 {
01084 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(id);
01085 return fChunk->getIterator();
01086 }
01087
01088 Chunk* DatabaseManagerImpl::getSystemTableChunk(CatalogTableID id)
01089 {
01090 return systemDatabase_->getSystemDatabaseChunk(id);
01091 }