void deleteRows(Object[] list, int start, int limit, boolean commit) { for (int i = start; i < limit; i++) { RowAction rowact = (RowAction) list[i]; if (rowact.type == RowActionBase.ACTION_DELETE_FINAL) { try { rowact.type = RowActionBase.ACTION_DELETE_COMMITTED; PersistentStore store = rowact.session.sessionData.getRowStore(rowact.table); Row row = rowact.memoryRow; if (row == null) { row = (Row) store.get(rowact.getPos(), false); } if (commit && rowact.table.hasLobColumn) { Object[] data = row.getData(); rowact.session.sessionData.removeLobUsageCount(rowact.table, data); } store.delete(row); store.remove(row.getPos()); } catch (HsqlException e) { // throw unexpectedException(e.getMessage()); } } } }
/** * Compare two rows of the table for inserting rows into unique indexes * * @param a data * @param b data * @return comparison result, -1,0,+1 * @throws HsqlException */ private int compareRowUnique(Session session, Row left, Row right) throws HsqlException { Object[] a = left.getData(); Object[] b = right.getData(); int j = 0; boolean hasNull = false; for (; j < colIndex.length; j++) { Object currentvalue = a[colIndex[j]]; int i = Column.compare(collation, currentvalue, b[colIndex[j]], colType[j]); if (i != 0) { return i; } if (currentvalue == null) { hasNull = true; } } if (isUnique && !useRowId && !hasNull) { return 0; } for (j = 0; j < pkCols.length; j++) { Object currentvalue = a[pkCols[j]]; int i = Column.compare(collation, currentvalue, b[pkCols[j]], pkTypes[j]); if (i != 0) { return i; } } if (useRowId) { int difference = left.getPos() - right.getPos(); if (difference < 0) { difference = -1; } else if (difference > 0) { difference = 1; } return difference; } return 0; }
void checkReferencedRows(Session paramSession, Table paramTable) { RowIterator localRowIterator = paramTable.rowIterator(paramSession); while (true) { Row localRow = localRowIterator.getNextRow(); if (localRow == null) break; Object[] arrayOfObject = localRow.getData(); checkInsert(paramSession, paramTable, arrayOfObject, false); } }
/** * Executes an UPDATE statement. It is assumed that the argument is of the correct type. * * @param cs a CompiledStatement of type CompiledStatement.UPDATE * @throws HsqlException if a database access error occurs * @return the result of executing the statement */ private Result executeUpdateStatement(CompiledStatement cs) throws HsqlException { Table table = cs.targetTable; TableFilter filter = cs.tf; int count = 0; if (filter.findFirst()) { int[] colmap = cs.columnMap; // column map Expression[] colvalues = cs.columnValues; Expression condition = cs.condition; // update condition int len = colvalues.length; HashMappedList rowset = new HashMappedList(); int size = table.getColumnCount(); int[] coltypes = table.getColumnTypes(); boolean success = false; do { if (condition == null || condition.test(session)) { try { Row row = filter.currentRow; Object[] ni = table.getNewRow(); System.arraycopy(row.getData(), 0, ni, 0, size); for (int i = 0; i < len; i++) { int ci = colmap[i]; ni[ci] = colvalues[i].getValue(session, coltypes[ci]); } rowset.add(row, ni); } catch (HsqlInternalException e) { } } } while (filter.next()); session.beginNestedTransaction(); try { count = table.update(session, rowset, colmap); success = true; } finally { // update failed (constraint violation) or succeeded session.endNestedTransaction(!success); } } updateResult.iUpdateCount = count; return updateResult; }
public Object[] getValues(Session session) { RowIterator it = table.rowIterator(session); if (it.hasNext()) { Row row = it.getNextRow(); if (it.hasNext()) { throw Error.error(ErrorCode.X_21000); } return row.getData(); } else { return new Object[table.getColumnCount()]; } }
/** * Find a node with matching data * * @param row row data * @return matching node * @throws HsqlException */ Node search(Session session, Row row) throws HsqlException { Object[] d = row.getData(); Node x = getRoot(session); while (x != null) { int c = compareRowUnique(session, row, x.getRow()); if (c == 0) { return x; } else if (c < 0) { x = x.getLeft(); } else { x = x.getRight(); } } return null; }
public boolean next() { if (isBeforeFirst) { isBeforeFirst = false; } else { if (it == null) { return false; } } currentRow = it.getNextRow(); if (currentRow == null) { return false; } else { currentData = currentRow.getData(); return true; } }
/** * Check used before creating a new foreign key cosntraint, this method checks all rows of a table * to ensure they all have a corresponding row in the main table. */ void checkReferencedRows(Session session, Table table, int[] rowColArray) { Index mainIndex = getMainIndex(); PersistentStore store = session.sessionData.getRowStore(table); RowIterator it = table.rowIterator(session); while (true) { Row row = it.getNextRow(); if (row == null) { break; } Object[] rowData = row.getData(); if (ArrayUtil.hasNull(rowData, rowColArray)) { if (core.matchType == OpTypes.MATCH_SIMPLE) { continue; } } else if (mainIndex.exists(session, store, rowData, rowColArray)) { continue; } if (ArrayUtil.hasAllNull(rowData, rowColArray)) { continue; } String colValues = ""; for (int i = 0; i < rowColArray.length; i++) { Object o = rowData[rowColArray[i]]; colValues += table.getColumnTypes()[i].convertToString(o); colValues += ","; } String[] info = new String[] {getName().name, getMain().getName().name}; throw Error.error(ErrorCode.X_23502, ErrorCode.CONSTRAINT, info); } }
public boolean commitTransaction(Session session) { if (session.abortTransaction) { return false; } int limit = session.rowActionList.size(); Object[] list = limit == 0 ? ValuePool.emptyObjectArray : session.rowActionList.getArray(); try { writeLock.lock(); endTransaction(session); if (limit == 0) { endTransactionTPL(session); try { session.logSequences(); } catch (HsqlException e) { } return true; } // new actionTimestamp used for commitTimestamp // already set in prepareCommitActions(); session.actionTimestamp = nextChangeTimestamp(); for (int i = 0; i < limit; i++) { RowAction action = (RowAction) list[i]; action.commit(session); } for (int i = 0; i < limit; i++) { RowAction action = (RowAction) list[i]; if (action.type == RowActionBase.ACTION_NONE) { continue; } int type = action.getCommitType(session.actionTimestamp); PersistentStore store = session.sessionData.getRowStore(action.table); Row row = action.memoryRow; if (row == null) { row = (Row) store.get(action.getPos(), false); } if (action.table.hasLobColumn) { switch (type) { case RowActionBase.ACTION_INSERT: session.sessionData.addLobUsageCount(action.table, row.getData()); break; default: } } if (action.table.tableType == TableBase.TEXT_TABLE) { switch (type) { case RowActionBase.ACTION_DELETE: store.removePersistence(action.getPos()); break; case RowActionBase.ACTION_INSERT: store.commitPersistence(row); break; default: } } } // session.actionTimestamp is the committed tx timestamp if (getFirstLiveTransactionTimestamp() > session.actionTimestamp) { mergeTransaction(session, list, 0, limit, session.actionTimestamp); rowActionMapRemoveTransaction(list, 0, limit, true); } else { list = session.rowActionList.toArray(); addToCommittedQueue(session, list); } try { session.logSequences(); database.logger.writeCommitStatement(session); } catch (HsqlException e) { } endTransactionTPL(session); return true; } finally { writeLock.unlock(); session.tempSet.clear(); } }
public void completeActions(Session session) { Object[] list = session.rowActionList.getArray(); int limit = session.rowActionList.size(); boolean canComplete = true; writeLock.lock(); try { for (int i = session.actionIndex; i < limit; i++) { RowAction rowact = (RowAction) list[i]; if (rowact.complete(session, session.tempSet)) { continue; } canComplete = false; if (session.isolationMode == SessionInterface.TX_REPEATABLE_READ || session.isolationMode == SessionInterface.TX_SERIALIZABLE) { session.abortTransaction = true; break; } } for (int i = session.actionIndex; canComplete && i < limit; i++) { RowAction action = (RowAction) list[i]; if (!action.table.isLogged) { continue; } Row row = action.memoryRow; if (row == null) { PersistentStore store = session.sessionData.getRowStore(action.table); row = (Row) store.get(action.getPos(), false); } Object[] data = row.getData(); try { int actionType = action.getActionType(session.actionTimestamp); if (actionType == RowActionBase.ACTION_INSERT) { database.logger.writeInsertStatement(session, (Table) action.table, data); } else if (actionType == RowActionBase.ACTION_DELETE) { database.logger.writeDeleteStatement(session, (Table) action.table, data); } else if (actionType == RowActionBase.ACTION_NONE) { // no logging } else { throw Error.runtimeError(ErrorCode.U_S0500, "TransactionManager"); } } catch (HsqlException e) { // can put db in special state } } if (!canComplete && !session.abortTransaction) { session.redoAction = true; rollbackAction(session); if (!session.tempSet.isEmpty()) { session.latch.setCount(session.tempSet.size()); for (int i = 0; i < session.tempSet.size(); i++) { Session current = (Session) session.tempSet.get(i); current.waitingSessions.add(session); // waitedSessions.put(current, session); // waitingSessions.put(session, current); } } } } finally { writeLock.unlock(); session.tempSet.clear(); } }