Index: System.Data.SQLite/SQLiteSession.cs ================================================================== --- System.Data.SQLite/SQLiteSession.cs +++ System.Data.SQLite/SQLiteSession.cs @@ -400,24 +400,30 @@ #endregion /////////////////////////////////////////////////////////////////////////// #region SQLiteChangeSetIterator Class - internal abstract class SQLiteChangeSetIterator : IDisposable + internal class SQLiteChangeSetIterator : IDisposable { #region Private Data private IntPtr iterator; + + /////////////////////////////////////////////////////////////////////// + + private bool ownHandle; #endregion /////////////////////////////////////////////////////////////////////// #region Protected Constructors protected SQLiteChangeSetIterator( - IntPtr iterator + IntPtr iterator, + bool ownHandle ) { this.iterator = iterator; + this.ownHandle = ownHandle; } #endregion /////////////////////////////////////////////////////////////////////// @@ -470,10 +476,21 @@ } #endregion /////////////////////////////////////////////////////////////////////// + #region Static "Factory" Methods + public static SQLiteChangeSetIterator Attach( + IntPtr iterator + ) + { + return new SQLiteChangeSetIterator(iterator, false); + } + #endregion + + /////////////////////////////////////////////////////////////////////// + #region IDisposable Members public void Dispose() { Dispose(true); GC.SuppressFinalize(this); @@ -514,12 +531,15 @@ // release unmanaged resources here... ////////////////////////////////////// if (iterator != IntPtr.Zero) { - UnsafeNativeMethods.sqlite3changeset_finalize( - iterator); + if (ownHandle) + { + UnsafeNativeMethods.sqlite3changeset_finalize( + iterator); + } iterator = IntPtr.Zero; } } } @@ -557,13 +577,14 @@ /////////////////////////////////////////////////////////////////////// #region Private Constructors private SQLiteMemoryChangeSetIterator( IntPtr pData, - IntPtr iterator + IntPtr iterator, + bool ownHandle ) - : base(iterator) + : base(iterator, ownHandle) { this.pData = pData; } #endregion @@ -593,11 +614,12 @@ ref iterator, nData, pData); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3changeset_start"); - result = new SQLiteMemoryChangeSetIterator(pData, iterator); + result = new SQLiteMemoryChangeSetIterator( + pData, iterator, true); } finally { if (result == null) { @@ -687,13 +709,14 @@ internal sealed class SQLiteStreamChangeSetIterator : SQLiteChangeSetIterator { #region Private Constructors private SQLiteStreamChangeSetIterator( - IntPtr iterator + IntPtr iterator, + bool ownHandle ) - : base(iterator) + : base(iterator, ownHandle) { // do nothing. } #endregion @@ -718,11 +741,11 @@ IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3changeset_start_strm"); - result = new SQLiteStreamChangeSetIterator(iterator); + result = new SQLiteStreamChangeSetIterator(iterator, true); } finally { if (result == null) { @@ -1670,10 +1693,22 @@ } #endregion /////////////////////////////////////////////////////////////////////// + #region Private Methods + private ISQLiteChangeSetMetadataItem CreateMetadataItem( + IntPtr iterator + ) + { + return new SQLiteChangeSetMetadataItem( + SQLiteChangeSetIterator.Attach(iterator)); + } + #endregion + + /////////////////////////////////////////////////////////////////////// + #region Protected Methods protected UnsafeNativeMethods.xSessionFilter GetDelegate( SessionTableFilterCallback tableFilterCallback, object clientData ) @@ -1734,14 +1769,21 @@ xConflict = new UnsafeNativeMethods.xSessionConflict( delegate(IntPtr context, SQLiteChangeSetConflictType type, IntPtr iterator) { - ISQLiteChangeSetMetadataItem item = null; - try { + ISQLiteChangeSetMetadataItem item = CreateMetadataItem( + iterator); + + if (item == null) + { + throw new SQLiteException( + "could not create metadata item"); + } + return conflictCallback(clientData, type, item); } catch (Exception e) { try