KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sessionsystem > SessionTable


1 package com.daffodilwoods.daffodildb.server.sessionsystem;
2
3 import java.sql.*;
4
5 import com.daffodilwoods.daffodildb.server.datasystem.interfaces.*;
6 import com.daffodilwoods.daffodildb.server.datasystem.mergesystem.*;
7 import com.daffodilwoods.daffodildb.server.datasystem.persistentsystem.*;
8 import com.daffodilwoods.daffodildb.server.datasystem.utility.*;
9 import com.daffodilwoods.daffodildb.server.datasystem.utility._Record;
10 import com.daffodilwoods.daffodildb.server.serversystem.*;
11 import com.daffodilwoods.daffodildb.server.sessionsystem.sessioncondition.*;
12 import com.daffodilwoods.daffodildb.server.sessionsystem.sessionversioninfo.*;
13 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
14 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.*;
15 import com.daffodilwoods.daffodildb.utils.*;
16 import com.daffodilwoods.daffodildb.utils.field.*;
17 import com.daffodilwoods.database.general.*;
18 import com.daffodilwoods.database.resource.*;
19 import com.daffodilwoods.database.utility.P;
20
21 /**
22  * <p>Title: SessionTable </p>
23  * Manages all the read and write operations. It maintains the system fields for
24  * each row and provides the iterator according to the isolation level of the session.
25  * it also maintains the synchonization on write operations. It is responsible
26  * for making the records ready to transfer in file system by providing transactionId.
27  * it fulfills the requirement of two phase commit by providing prepare and
28  * make persistent methods. It also provide the events for every operation that
29  * is done by itself.
30  */

31 public class SessionTable extends StatementHandler implements _SessionTable, Cloneable JavaDoc {
32
33    private TableRowIdGetter tableRowIdGetter;
34
35    /**
36     * These variables are used for optimization pupose
37     */

38    Lock tableLock;
39    ForUpdateTableHandler forUpdTableHndlr;
40    public static final int sessionTable = 0;
41    public static final int tableType = 0;
42    _Iterator insertIterator;
43    private SessionRowLocker rowLocker;
44    SessionVersionHandler sessionVersionHandler;
45    MakePersistentForInsertedCondition conditionForInsertion ;
46    InvalidRecordCondition conditionForDeletion ;
47    int operationCount;
48
49
50
51
52    public String JavaDoc toString() {
53       return tableName.getIdentifier();
54    }
55
56    /**
57     * Constructs the Session Table
58     * @param tableName Qualified name of the table
59     * @param session session for which this object is taken
60     * @param mergeTable For read and write operations in memory and file
61     * @param tableRowIdGetter To get the next rowid
62     * @throws DException
63     */

64    public SessionTable(QualifiedIdentifier tableName0, _Session session0, _Table mergeTable0, TableRowIdGetter tableRowIdGetter0, ForUpdateTableHandler forUpdateTableHandler0, SessionVersionHandler sessionVersionHandler0) throws DException {
65       super(session0, mergeTable0, tableName0, sessionVersionHandler0);
66       tableRowIdGetter = tableRowIdGetter0;
67       forUpdTableHndlr = forUpdateTableHandler0;
68       sessionVersionHandler = sessionVersionHandler0;
69       tableLock = new Lock();
70       insertIterator = ( (MergeTable) mergeTable).getMemoryTable().getDefaultIterator();
71       /* here we need to get superMostSessionId because all records are committed in superMostSessionId
72        otherwise condition is not solved in transferRecords and records are not committed.
73        */

74        conditionForInsertion = new MakePersistentForInsertedCondition(((Session)session).getSuperMostSessionId() );
75          conditionForDeletion = new InvalidRecordCondition(
76             ((Session)session).getSuperMostSessionId() );
77       operationCount = 0;
78    }
79
80    public TableRowIdGetter getTableRowIdGetter() throws DException {
81       return tableRowIdGetter;
82    }
83
84    /**
85     * Providess the merge table which in turn is a combination of File Table and Memory Table
86     * @return _Table
87     * @throws DException
88     */

89
90    public _Table getMergeTable() throws DException {
91       return mergeTable;
92    }
93
94    /**
95     * updates the row with next row id, session id, and passes the values to record to update the system fields.
96     * @param record
97     * @param systemFields indexes of the columns
98     * @param defaultValues values by which record is to be updated
99     * @throws DException
100     */

101
102    void updateSystemFields(_Record record, int[] systemFields, Object JavaDoc[] defaultValues) throws DException {
103       for (int i = 0; i < systemFields.length; i++) {
104          Object JavaDoc value = defaultValues[i];
105          if (systemFields[i] == SystemFields.rowId) {
106             value = tableRowIdGetter.getNextRowId();
107          }
108          if (systemFields[i] == (SystemFields.sessionId)) {
109             value = session.getSessionId();
110          }
111          record.update(systemFields[i], value);
112       }
113    }
114
115    private void updateSystemFieldsAndUserFields(RecordVersion record, int[] columns, Object JavaDoc[] values) throws DException {
116       record.update(SystemFields.sessionId, session.getSessionId());
117       record.update(SystemFields.transactionId, SystemFields.maxIntegerValue);
118       record.update(SystemFields.invalidSessionId, SystemFields.maxIntegerValue);
119       record.update(columns, values);
120    }
121
122    /**
123     * return true if a row is locked otherwise false
124     * @param <b>record</b>
125     * @return boolean
126     * @throws DException
127     */

128
129    public boolean isRowLocked(_Record record) throws DException {
130       return! (record.getObject(SystemFields.invalidSessionId).equals(SystemFields.maxIntegerValue));
131    }
132
133    /**
134     * Provides the information whether should we create a new version or not.
135     * @param record record for which we have to do the checking
136     * @return boolean
137     * @throws DException
138     */

139
140    private boolean createVersion(_Record record) throws DException {
141       Object JavaDoc transactionId = record.getObject(SystemFields.transactionId);
142       Object JavaDoc sessionId = record.getObject(SystemFields.sessionId);
143       if (transactionId.equals(SystemFields.maxIntegerValue) && sessionId.equals(session.getSessionId())) {
144          return false;
145       }
146       return true;
147    }
148
149    /**
150     * Provide Qualified name of the table
151     * @return QualifiedIdentifier
152     */

153
154    public QualifiedIdentifier getTableName() {
155       return tableName;
156    }
157
158    public Lock getSessionLock() throws DException {
159       return tableLock;
160    }
161
162    /**
163     * After getting lock for write operation it inserts a record in table using the
164     * iterator
165     * @param columnIndexes indexes of the columns
166     * @param values values which are to be inserted
167     * @return returns the event of type insert
168     * @throws DException
169     */

170
171    public RecordVersion insert(int[] columnIndexes, Object JavaDoc[] values) throws DException {
172       if (session.getIsolationLevel() == Session.ReadUncommitted) {
173          throw new SessionException("DSE487", null);
174       }
175       if (!performCommit) {
176          session.addTableInChangedTableList(tableName);
177          performCommit = true;
178       }
179       sessionIdAtCommitInParent = session.getSessionId();
180       session.updateDataModifiedStatus();
181       try {
182          tableLock.lock(0);
183          _Record record = mergeTable.getBlankRecord();
184          int[] systemFields = SystemFieldsCharacteristics.getSystemFields();
185          Object JavaDoc[] systemFieldsDefaultValues = SystemFieldsCharacteristics.defaultValues();
186          record.update(columnIndexes, values);
187          updateSystemFields(record, systemFields, systemFieldsDefaultValues);
188
189          ( (_TableOperations) insertIterator).insert(record.getObject());
190          if (!session.getAutoCommit()) {
191             Object JavaDoc key = record.getObject(SystemFieldsCharacteristics.RTS); //new int[] {SystemFields.rowId, SystemFields.transactionId, SystemFields.sessionId} );
192
insert(session.getSessionId(), key);
193          }
194          insert = true;
195          operationCount ++;
196          return new RecordVersion(record);
197       } finally {
198          tableLock.unLock();
199       }
200
201    }
202
203    /**
204     *
205     * It updates the record which is present at the current pointer of the iterator.
206     *
207     * For upading it performs following steps
208     * 1. It takes operational lock (which includes insert, update, delete) against
209     * commit and rollback.
210     * 2. Fetches the rowId from the iterator to take the row level lock to prevent other
211     * users to do insert, update or delete operation on the same record.
212     * 3. Ensures record in memory, means if the current pointer of iterator is set on file
213     * and the same record is present in memory then it just changes its pointer to memory.
214     * 4. Gets the record from iterator and checks whether the record has not been updated or
215     * deleted by any other user.
216     * 5. Checks whether to create a new version of record or not.
217     * i. A new version is created if the record is committed or have the different
218     * sessionId from the current session's Id.
219     * 6. Set the status false if any of the column being updated is having the type blob/clob.
220     * 7. Move the iterator on the pointer where it was before updation.
221     *
222     * values.
223     * @param iterator iterator whose current record is to be updated
224     * @param columns index of the column which are to be updated
225     * @param values values by which the record is to be updated
226     * @return returns a event with the type update
227     * @throws DException
228     */

229
230    public RecordVersion update(_Iterator iterator, int[] columns, Object JavaDoc[] values) throws DException {
231       tableLock.lock(0);
232       if (session.getIsolationLevel() == Session.ReadUncommitted) {
233          throw new SessionException("DSE1164", null);
234       }
235       if (!performCommit) {
236          session.addTableInChangedTableList(tableName);
237          performCommit = true;
238       }
239       sessionIdAtCommitInParent = session.getSessionId();
240       session.updateDataModifiedStatus();
241       try {
242          Object JavaDoc rowId = (iterator.getColumnValues(SessionConditionReferences.rowIdReference_0));
243          rowLocker.lockRow(rowId);
244          try {
245             ( (_IndexIteratorInfo) iterator).ensureRecordInMemory();
246             _Record record = iterator.getRecord();
247             if (isRowLocked(record)) {
248          ;//// Removed By Program ** System.out.println(session.getIsolationLevel() +"session id ="+session.getSessionId() +" tableName ="+tableName+" row Alock found for user "+ Thread.currentThread()+ " record "+ P.print(record.getObject()));
249
throw new SessionException("DSE879", null);
250             }
251             forUpdTableHndlr.checkRowValidity( ( (Session) session).getSuperMostSessionId(), record);
252             Record cloneRecord = (Record) record.clone();
253             boolean createVersion = createVersion(record);
254             RecordVersion recordVersion = new RecordVersion(cloneRecord);
255
256             updateSystemFieldsAndUserFields(recordVersion, columns, values);
257             Object JavaDoc[] oldKey = record.getObject(SystemFieldsCharacteristics.RTS); //new int[] {SystemFields.rowId, SystemFields.transactionId, SystemFields.sessionId} );
258
if (createVersion) {
259                ( (_TableOperations) iterator).update(SystemFieldsCharacteristics.IS, new Object JavaDoc[] {session.getSessionId()});
260                setStatusForDBlobColumn(record, columns, values);
261                Object JavaDoc[] valuesToInsert = (Object JavaDoc[]) recordVersion.getCurrentRecord().getObject();
262
263                ( (_TableOperations) insertIterator).insert(valuesToInsert);
264                if (!session.getAutoCommit()) {
265                   Object JavaDoc newKey = new Object JavaDoc[] {
266                       valuesToInsert[SystemFields.rowId],
267                       valuesToInsert[SystemFields.transactionId],
268                       valuesToInsert[SystemFields.sessionId]};
269                   insert(session.getSessionId(), newKey);
270                   update(session.getSessionId(), oldKey);
271                }
272             } else {
273                ( (_TableOperations) iterator).update(columns, values);
274             }
275                  if(tableName.getName().equalsIgnoreCase("AD_Sequence") ){
276          ;//// Removed By Program ** System.out.println(Thread.currentThread() +" Session ID >> " + session.getSessionId() +
277
}
278
279             if (insert) {
280                insertDelete = true;
281             }
282             delete = true;
283             insert = true;
284             if (!oldKey[1].equals(SystemFields.maxIntegerValue))
285                chageInCommittedRecord = true;
286             operationCount += 2;
287             return recordVersion;
288          } finally {
289             rowLocker.unLockRow(rowId);
290          }
291       } finally {
292          tableLock.unLock();
293       }
294    }
295
296    private void setStatusForDBlobColumn(_Record record, int[] columns, Object JavaDoc[] values) throws DException {
297       _TableCharacteristics tableCharacteristics = mergeTable.
298           getTableCharacteristics();
299       if (tableCharacteristics.isBlobClobTable() > 0) {
300          if (!record.getObject(SystemFields.transactionId).equals(SystemFields.
301              maxIntegerValue)) {
302             for (int i = 0; i < columns.length; i++) {
303                if ( (! ( (FieldBase) values[i]).getNull()) &&
304                    (tableCharacteristics.isBlobClob(columns[i]))) {
305                   ( (DBlobUpdatable) values[i]).setDBLob(false);
306                }
307             }
308          } else {
309             for (int i = 0; i < tableCharacteristics.getColumnCount(); i++) {
310                if (tableCharacteristics.isBlobClob(i)) {
311                   if (!isUpdatedColumn(i, columns)) {
312                      DBlobUpdatable dblobUpdatabale = ( (DBlobUpdatable) record.
313                          getObject(i));
314                      dblobUpdatabale.setDBLob(true);
315                   }
316                }
317             }
318          }
319       }
320    }
321
322    /**
323     * Deletes the current record of the iterator .
324     * For deleting it performs following steps
325     * 1. It takes operational lock (which includes insert, update, delete) against
326     * commit and rollback.
327     * 2. Fetches the rowId from the iterator to take the row level lock to prevent other
328     * users to do insert, update or delete operation on the same record.
329     * 3. Ensures record in memory, means if the current pointer of iterator is set on file
330     * and the same record is present in memory then it just changes its pointer to memory.
331     * 4. Gets the record from iterator and checks whether the record has not been updated or
332     * deleted by any other user.
333     * 5. Updates the invalidSessionId of the record to mark it as deleted.
334     *
335     * @param iterator iterator whose current record is to be updated
336     * @return returns a event with the type delete
337     * @throws DException
338     */

339
340    public RecordVersion delete(_Iterator iterator) throws DException {
341       tableLock.lock(0);
342       if (session.getIsolationLevel() == Session.ReadUncommitted) {
343          throw new SessionException("DSE330", null);
344       }
345       if (!performCommit) {
346          session.addTableInChangedTableList(tableName);
347          performCommit = true;
348       }
349       sessionIdAtCommitInParent = session.getSessionId();
350       session.updateDataModifiedStatus();
351       try {
352          Object JavaDoc rowId = (iterator.getColumnValues(SessionConditionReferences.rowIdReference_0));
353          rowLocker.lockRow(rowId);
354          try {
355             ( (_IndexIteratorInfo) iterator).ensureRecordInMemory();
356             _Record record = iterator.getRecord();
357             if (isRowLocked(record)) {
358                throw new SessionException("DSE879", null);
359             }
360             forUpdTableHndlr.checkRowValidity( ( (Session) session).getSuperMostSessionId(), record);
361             RecordVersion recordVersion = new RecordVersion(record);
362             ( (_TableOperations) iterator).update(SystemFieldsCharacteristics.IS, new Object JavaDoc[] {session.getSessionId()});
363             if (!session.getAutoCommit()) {
364                Object JavaDoc[] oldKey = record.getObject(SystemFieldsCharacteristics.RTS); //new int[] {SystemFields.rowId, SystemFields.transactionId, SystemFields.sessionId} );
365
delete(session.getSessionId(), oldKey);
366             }
367             if (insert) {
368                insertDelete = true;
369             }
370             delete = true;
371             operationCount++;
372             return recordVersion;
373          } finally {
374             rowLocker.unLockRow(rowId);
375          }
376       } finally {
377          tableLock.unLock();
378       }
379    }
380
381    /**
382     * Provides the Iterator according to the Isolation Level.
383     * @param condition
384     * @param runTimeVariables
385     * @return _Iterator
386     * @throws DException
387     */

388
389    public _Iterator getIterator(_SingleTableExecuter singleTableExecuter, _ServerSession serverSession) throws DException {
390       return ( (Session) session).getDataRetriever().getIterator(mergeTable, singleTableExecuter, serverSession, tableName, forUpdTableHndlr);
391    }
392
393    public void performCommitInParent(Object JavaDoc parentSessionId, _StatementExecutionContext statementExecutionContext) throws DException {
394       super.performCommitInParent(parentSessionId, statementExecutionContext);
395    }
396
397    public void performRollBack(_StatementExecutionContext statementExecutionContext) throws DException {
398       super.performRollBack(statementExecutionContext);
399       operationCount = 0;
400    }
401
402    public void performRollBackWithChildSession(_StatementExecutionContext statementExecutionContext) throws DException {
403       super.performRollBackWithChildSession(statementExecutionContext);
404    }
405
406    public _Iterator getForeignConstraintIterator(_SingleTableExecuter conditionExecuter, _IndexTable foreignConstraintTable) throws DException {
407       return ( (Session) session).getDataRetriever().getFCIterator(mergeTable, tableName, conditionExecuter, foreignConstraintTable);
408    }
409
410    public int getTableType() throws DException {
411       return tableType;
412    }
413
414    public boolean isDataModified() throws DException {
415       return super.isDataModified();
416    }
417
418    public void setPerformCommit(boolean performCommit0) throws DException {
419       performCommit = performCommit0;
420    }
421
422    public RecordVersion deleteVersion(_Iterator parm1, Date date) throws com.daffodilwoods.database.resource.DException {
423       /**@todo Implement this com.daffodilwoods.daffodildb.server.sessionsystem._SessionTable method*/
424       throw new java.lang.UnsupportedOperationException JavaDoc("Method deleteVersion() not yet implemented.");
425    }
426
427    public RecordVersion updateVersion(_Iterator parm1, int[] parm2, Object JavaDoc[] parm3, Date parm4) throws com.daffodilwoods.database.resource.DException {
428       /**@todo Implement this com.daffodilwoods.daffodildb.server.sessionsystem._SessionTable method*/
429       throw new java.lang.UnsupportedOperationException JavaDoc("Method updateVersion() not yet implemented.");
430    }
431
432    public RecordVersion insertVersion(int[] columnIndexes, Object JavaDoc[] values, Date date) throws DException {
433       /**@todo Implement this com.daffodilwoods.daffodildb.server.sessionsystem._SessionTable method*/
434       throw new java.lang.UnsupportedOperationException JavaDoc("Method insertVersion() not yet implemented.");
435    }
436
437    public void removeSession() {
438       forUpdTableHndlr.removeSession( ( (Session) session).getSuperMostSessionId());
439    }
440
441    public void setRowLocker(SessionRowLocker rowLocker0) {
442       rowLocker = rowLocker0;
443    }
444
445    public _Iterator getConditionalIterator(_SingleTableExecuter singleTableExecuter, _ServerSession serverSession) throws DException {
446       return ( (Session) session).getDataRetriever().getConditionalIterator(mergeTable, singleTableExecuter, serverSession, tableName, forUpdTableHndlr);
447    }
448
449    public void transferRecords(_DatabaseUser user, Object JavaDoc transactionId, boolean isAnyDependentTransaction) throws DException {
450       _IndexTable fileTable = ( (MergeTable) mergeTable).getFileTable();
451       _IndexTable memoryTable = ( (MergeTable) mergeTable).getMemoryTable();
452       _Iterator memoryIterator = memoryTable.getDefaultIterator();
453       _Iterator fileIterator = fileTable.getDefaultIterator();
454        if (memoryIterator.last()) {
455          int recordsTraverssed = 0;
456          Object JavaDoc keyOfUpdated = null;
457             do {
458               try{
459             boolean deleteChecking = true;
460             Object JavaDoc[] values = (Object JavaDoc[]) memoryIterator.getColumnValues();
461             Object JavaDoc key = values[0];
462             if(keyOfUpdated != null && keyOfUpdated.equals(key) ){
463                 recordsTraverssed ++;
464               if (!isAnyDependentTransaction)
465                     ( (_TableOperations) memoryIterator).delete();
466                   keyOfUpdated = null;
467              }else{
468               keyOfUpdated = null;
469               if (insert) {
470                 if (conditionForInsertion.evaluateWithValues(values)) {
471                     recordsTraverssed ++;
472                   deleteChecking = false;
473                   values[SystemFields.transactionId] = transactionId;
474                   if (chageInCommittedRecord &&
475                       sessionVersionHandler.seek(fileIterator, key)) {
476                     keyOfUpdated = key;
477                     ( (_UserTableOperations) fileIterator).update(user,
478                         values);
479                   }
480                   else {
481                     ( (_UserTableOperations) fileIterator).insert(user,
482                         values);
483
484                   }
485                   ( (_TableOperations) memoryIterator).delete();
486                  }
487               }
488               if (deleteChecking && delete) {
489                 if (conditionForDeletion.evaluateWithValues(values)) {
490                     recordsTraverssed ++;
491                   Object JavaDoc actualKey = ( (_IndexIteratorInfo) memoryIterator).
492                       getActualKey();
493                   Object JavaDoc key1 = ( (_Key) actualKey).getKeyValue();
494                   Object JavaDoc[] keyT = new Object JavaDoc[] {
495                       values[SystemFields.transactionId],
496                       values[SystemFields.sessionId]};
497                   if (sessionVersionHandler.recordFound(fileIterator, key1, keyT)) {
498                     ( (_UserTableOperations) fileIterator).delete(user);
499                   }
500                   if (!isAnyDependentTransaction)
501                     ( (_TableOperations) memoryIterator).delete();
502                   }
503               }
504             }
505             if(recordsTraverssed == operationCount){
506               break;
507             }
508           }catch(DException de){
509             if(! de.getDseCode().equalsIgnoreCase("DSE2004") )
510               throw de;
511            }
512
513          } while (memoryIterator.previous());
514          }
515       transactionStarted = false;
516       keyTracer.resetLastSessionId();
517       operationCount = 0;
518    }
519
520    private boolean isUpdatedColumn(int index, int[] columns) {
521       for (int i = 0; i < columns.length; i++) {
522          if (columns[i] == index)
523             return true;
524       }
525       return false;
526    }
527 }
528
Popular Tags