Added error checking for insertTuple
[csql.git] / src / server / Transaction.cxx
blobd9ffe45ec1bfb01a0b7f009e06e0bb0937b18731
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 ***************************************************************************/
16 #include<Transaction.h>
17 #include<Lock.h>
18 #include<Database.h>
19 #include<Allocator.h>
20 #include<CatalogTables.h>
21 #include<Debug.h>
23 DbRetVal Transaction::insertIntoHasList(Database *sysdb, LockHashNode *node)
25 //allocate lock node
26 Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
27 DbRetVal rv = OK;
28 TransHasNode *hasNode = (TransHasNode*)chunk->allocate(sysdb, &rv);
29 if (NULL == hasNode)
31 printError(rv, "Could not allocate Lock node");
32 return rv;
34 printDebug(DM_Transaction, "insertIntoHasList new TransHasNode created:%x",
35 hasNode);
36 hasNode->node_ = node;
37 hasNode->next_ = NULL;
38 if (NULL == hasLockList_)
40 printDebug(DM_Transaction, "hasLockList is null:It is now %x",hasNode);
41 hasLockList_ = hasNode;
42 return OK;
45 TransHasNode *it = hasLockList_;
46 while (NULL != it->next_) { it = it->next_; }
47 it->next_ = hasNode;
48 printDebug(DM_Transaction, "Added to hasLockList at end:%x",it);
49 return OK;
52 DbRetVal Transaction::removeFromHasList(Database *sysdb, void *tuple)
54 Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
55 TransHasNode *iter = hasLockList_, *prev = hasLockList_;
56 if (NULL == iter)
58 printError(ErrNotFound, "There are no tuple lock in has list.");
59 return ErrNotFound;
61 while (iter != NULL)
63 if (tuple == iter->node_->ptrToTuple_)
65 prev->next_ = iter->next_;
66 chunk->free(sysdb, iter);
67 if (iter == hasLockList_) hasLockList_ = NULL;
68 return OK;
70 prev = iter;
71 iter = iter->next_;
73 printError(ErrNotFound, "There are no tuple lock in has list.");
74 return ErrNotFound;
78 DbRetVal Transaction::releaseAllLocks(LockManager *lockManager_)
80 Database *sysdb =lockManager_->systemDatabase_;
81 Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
82 TransHasNode *iter = hasLockList_, *prev;
83 while (NULL != iter)
85 prev = iter;
86 iter = iter->next_;
87 printDebug(DM_Transaction, "Releasing lock %x",prev->node_->ptrToTuple_);
88 lockManager_->releaseLock(prev->node_->ptrToTuple_);
89 chunk->free(sysdb, prev);
91 hasLockList_ = NULL;
92 return OK;
94 bool Transaction::findInHasList(Database *sysdb, LockHashNode *node)
96 TransHasNode *iter = hasLockList_;
97 while (NULL != iter)
99 if (iter->node_ == node) return true;
100 iter = iter->next_;
102 return false;
105 DbRetVal Transaction::appendUndoLog(Database *sysdb, OperationType type,
106 void *data, size_t size)
108 DbRetVal rv =OK;
109 UndoLogInfo *logInfo = createUndoLog(sysdb, type, data, size, &rv);
110 if (logInfo == NULL) return rv;
111 os::memcpy((char*)logInfo + sizeof(UndoLogInfo), data, size);
112 addAtBegin(logInfo);
113 printDebug(DM_Transaction, "creating undo log and append %x optype:%d",
114 logInfo, type);
115 return OK;
120 DbRetVal Transaction::appendLogicalUndoLog(Database *sysdb, OperationType type, void *data,
121 size_t size, void* indexPtr)
123 DbRetVal rv = OK;
124 UndoLogInfo *logInfo = createUndoLog(sysdb, type, data, size, &rv);
125 if (logInfo == NULL) return rv;
126 char **indPtr = (char**)((char*)logInfo + sizeof(UndoLogInfo));
127 *indPtr = (char*) indexPtr;
128 addAtBegin(logInfo);
129 printDebug(DM_Transaction, "creating logical undo log and append %x optype:%d",
130 logInfo, type);
131 return rv;
134 UndoLogInfo* Transaction::createUndoLog(Database *sysdb, OperationType type, void *data,
135 size_t size, DbRetVal *rv)
137 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
138 UndoLogInfo *logInfo = (UndoLogInfo*)chunk->allocate(sysdb,
139 size + sizeof(UndoLogInfo), rv);
140 if (logInfo == NULL) {
141 printError(*rv, "Unable to allocate undo log record\n");
142 return NULL;
144 logInfo->opType_ = type;
145 logInfo->ptrToTuple_ = data;
146 logInfo->size_ = size;
147 logInfo->next_ = NULL;
148 return logInfo;
151 void Transaction::addAtBegin(UndoLogInfo* logInfo)
153 //add it to the begin of the log list
154 logInfo->next_ = firstUndoLog_;
155 firstUndoLog_ = logInfo;
156 return;
159 UndoLogInfo* Transaction::popUndoLog()
161 UndoLogInfo *iter = firstUndoLog_, *prev = firstUndoLog_;
162 if(NULL != iter)
164 prev = iter;
165 iter = iter->next_;
167 firstUndoLog_ = iter;
168 return prev;
172 int Transaction::noOfUndoLogs()
174 UndoLogInfo *iter = firstUndoLog_;
175 int count =0;
176 while(NULL != iter)
178 count++;
179 iter = iter->next_;
181 return count;
183 void Transaction::printDebugInfo(Database *sysdb)
185 printf("<TransactionInfo>\n");
186 if (waitLock_ != NULL)
188 printf("<WaitLock>");
189 waitLock_->print();
190 printf("</WaitLock>");
193 printf("<UndoLogs>\n");
194 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
195 printf(" <TotalPages> %d </TotalPages>\n", chunk->totalPages());
196 UndoLogInfo *iter = firstUndoLog_;
197 int count =0;
198 while(NULL != iter)
200 iter->print();
201 iter = iter->next_;
202 count++;
204 printf("</TotalNodes> %d </TotalNodes>\n", count);
205 printf("</UndoLogs>\n");
207 printf("<TransHasList>\n");
208 chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
209 printf(" <TotalPages> %d </TotalPages>\n", chunk->totalPages());
210 TransHasNode *hasIter = hasLockList_;
211 count =0;
212 while (NULL != hasIter)
214 hasIter->print();
215 hasIter = hasIter->next_;
216 count++;
218 printf("</TotalNodes> %d </TotalNodes>\n", count);
219 printf("</TransHasList>\n");
221 printf("</TransactionInfo>\n");
222 return ;
224 DbRetVal Transaction::removeUndoLogs(Database *sysdb)
226 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
227 UndoLogInfo *logInfo = NULL;
228 while(NULL != (logInfo = popUndoLog()))
230 chunk->free(sysdb, logInfo);
232 return OK;
236 DbRetVal Transaction::applyUndoLogs(Database *sysdb)
238 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
239 UndoLogInfo *logInfo = NULL;
240 while(NULL != (logInfo = popUndoLog()))
242 switch(logInfo->opType_)
244 case InsertOperation:
245 *((int*)(logInfo->ptrToTuple_) - 1) = 0;
246 //May memcpy is not needed as no one will update this
247 //as lock is taken on this tuple
248 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
249 sizeof(UndoLogInfo), logInfo->size_);
250 break;
251 case DeleteOperation:
252 *((int*)(logInfo->ptrToTuple_) - 1) = 1;
253 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
254 sizeof(UndoLogInfo), logInfo->size_);
255 break;
256 case UpdateOperation:
257 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
258 sizeof(UndoLogInfo), logInfo->size_);
259 break;
261 case InsertHashIndexOperation:
262 //TODO
263 break;
264 case UpdateHashIndexOperation:
265 //TODO
266 break;
267 case DeleteHashIndexOperation:
268 //TODO
269 break;
271 chunk->free(sysdb, logInfo);
273 return OK;