/// /// Copyright © 2003-2008 JetBrains s.r.o. /// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder). /// using System; using System.Collections; using System.IO; using JetBrains.Omea.Containers; using JetBrains.Omea.Database; namespace JetBrains.Omea.ResourceStore { /// /// Result set enumerator which supports uniform exception handling. /// internal abstract class SafeRecordEnumeratorBase: IDisposable { private IResultSet _resultSet; protected IEnumerator _baseEnumerator; protected IRecord _currentRecord; private string _operation; private bool _ioError = false; protected SafeRecordEnumeratorBase( IResultSet resultSet, string operation ) { _resultSet = resultSet; _operation = operation; try { _baseEnumerator = resultSet.GetEnumerator(); } catch( IOException ex ) { _ioError = true; _resultSet.Dispose(); MyPalStorage.Storage.OnIOErrorDetected( ex ); _baseEnumerator = null; } } public bool MoveNext() { if ( _baseEnumerator == null ) { return false; } while( true ) { bool result; try { result = _baseEnumerator.MoveNext(); } catch( IOException ex ) { _ioError = true; _resultSet.Dispose(); MyPalStorage.Storage.OnIOErrorDetected( ex ); return false; } catch( BadIndexesException ) { MyPalStorage.Storage.OnIndexCorruptionDetected( "Bad indexes found in " + _operation ); return false; } if ( !result ) { return false; } try { LoadCurrentRecord(); } catch( IOException ex ) { _ioError = true; _resultSet.Dispose(); MyPalStorage.Storage.OnIOErrorDetected( ex ); return false; } catch( BadIndexesException ) { MyPalStorage.Storage.OnIndexCorruptionDetected( "Bad indexes found in " + _operation ); continue; } return true; } } protected abstract void LoadCurrentRecord(); public void Dispose() { IDisposable disp = _baseEnumerator as IDisposable; if ( disp != null ) { disp.Dispose(); } } public bool IOError { get { return _ioError; } } } /// /// Enumerator which provides direct access to records. /// internal class SafeRecordEnumerator: SafeRecordEnumeratorBase { public SafeRecordEnumerator( IResultSet resultSet, string operation ) : base( resultSet, operation ) { } protected override void LoadCurrentRecord() { _currentRecord = (IRecord) _baseEnumerator.Current; } public IRecord Current { get { return _currentRecord; } } } /// /// Enumerator which provides access to values in records. /// internal class SafeRecordValueEnumerator: SafeRecordEnumeratorBase { private IRecordEnumerator _recordEnumerator; public SafeRecordValueEnumerator( IResultSet resultSet, string operation ) : base( resultSet, operation ) { _recordEnumerator = _baseEnumerator as IRecordEnumerator; } protected override void LoadCurrentRecord() { if ( _recordEnumerator == null ) { _currentRecord = (IRecord) _baseEnumerator.Current; } } public object GetCurrentValue( int column ) { if ( _recordEnumerator != null ) { return _recordEnumerator.GetCurrentRecordValue( column ); } return _currentRecord.GetValue( column ); } public int GetCurrentIntValue( int column ) { if ( _recordEnumerator != null ) { return (int) _recordEnumerator.GetCurrentRecordValue( column ); } return _currentRecord.GetIntValue( column ); } } }