Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / DataSource.cs / 1 / DataSource.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace Microsoft.InfoCards { using System; using System.Collections.Generic; using System.Globalization; using System.Threading; using Microsoft.InfoCards.Diagnostics; using System.ServiceModel.Diagnostics; using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace; // // Summary: // Abstract base class for all data sources in the inforcard system. // // Remarks: // Currently, only FileDataSource exists, but during the original design, // we had the requirement for an AD data source, so we have left this // abstracted implementation alone, for future expansion. // internal abstract class DataSource : IDisposable { string m_instanceId; bool m_isLoaded; ReaderWriterLock m_lock; bool m_isDisposed; string m_sourceId; bool m_isCleared; protected DataSource( string instanceId, string sourceId ) { m_instanceId = instanceId; m_sourceId = sourceId; m_lock = new ReaderWriterLock( ); } public string SourceId { get { ThrowIfDisposed( ); return m_sourceId; } } public bool IsDisposed { get { return m_isDisposed; } } public bool IsLoaded { get { ThrowIfDisposed( ); return m_isLoaded; } } public bool IsCleared { get { return m_isCleared; } set { m_isCleared = value; } } protected internal string InstanceId { get { ThrowIfDisposed( ); return m_instanceId; } set { ThrowIfDisposed( ); m_instanceId = value; } } public bool IsProcessingTransaction() { ThrowIfDisposed(); ThrowIfNotLoaded(); return m_lock.IsWriterLockHeld; } public void BeginTransaction() { ThrowIfWriteLockHeld(); ThrowIfDisposed( ); ThrowIfNotLoaded( ); IDT.TraceVerbose( TraceCode.StoreBeginTransaction, SourceId ); m_lock.AcquireWriterLock( 0 ); OnBeginTransaction( ); } public void CommitTransaction() { ThrowIfDisposed( ); ThrowIfNotLoaded( ); ThrowIfWriteLockNotHeld( ); IDT.TraceVerbose( TraceCode.StoreCommitTransaction, SourceId ); OnCommitTransaction( ); m_lock.ReleaseWriterLock( ); } public void RollbackTransaction() { ThrowIfDisposed( ); ThrowIfNotLoaded( ); ThrowIfWriteLockNotHeld( ); IDT.TraceVerbose( TraceCode.StoreRollbackTransaction, SourceId ); OnRollbackTransaction( ); m_lock.ReleaseWriterLock( ); } public void Load() { ThrowIfDisposed( ); IDT.TraceVerbose( TraceCode.StoreLoading, SourceId ); OnLoad( ); m_isLoaded = true; } public void Clear() { ThrowIfLoaded(); ThrowIfDisposed(); IDT.TraceVerbose( TraceCode.StoreDeleting, SourceId ); OnClear(); m_isLoaded = false; m_isCleared = true; } public void Close() { if( m_isLoaded ) { IDT.TraceVerbose( TraceCode.StoreClosing, SourceId ); OnClose( ); m_isLoaded = false; } } public DataRow GetSingleRow( params QueryParameter[] objectQuery ) { return GetSingleRow( QueryDetails.FullRow,objectQuery ); } public DataRow GetSingleRow( QueryDetails details, params QueryParameter[] objectQuery ) { IListlist = Query( details,objectQuery ); if( null == list || 0 == list.Count ) { return null; } else if( list.Count > 1 ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.StoreMoreThanOneRowReturnedInSingleMatchQuery ) ) ); } else { return list[ 0 ]; } } public IList Query( params QueryParameter[] objectQuery ) { return Query( QueryDetails.FullRow, objectQuery ); } public IList Query( QueryDetails details, params QueryParameter[] objectQuery ) { ThrowIfDisposed( ); ThrowIfNotLoaded( ); if( null == objectQuery || 0 == objectQuery.Length ) { throw IDT.ThrowHelperArgumentNull( "query" ); } if( !IsValidQueryDetails( details ) ) { throw IDT.ThrowHelperError( new ArgumentException( "details" ) ); } if( QueryDetails.None == details ) { return null; } List rows = null; LocalIdCollection localIds = null; LocalIdCollection queryIds = null; // // Get a Reader lock on the data. // bool lockHeld = false; try { try { } finally { m_lock.AcquireReaderLock( 0 ); lockHeld = true; } IDT.TraceDebug( "STORE: Begining DataSource query on {0}", SourceId ); IDT.TraceDebug( "STORE: Query Details\n\t\tDetailLevel:{0}\n\t\tParamCount:{1}\n\t\tPrimaryParameter:{2}", details.ToString(), objectQuery.Length, objectQuery[ 0 ].IndexName ); IDT.TraceDebug( "STORE: Begining Search Process on {0}", SourceId ); foreach( QueryParameter q in objectQuery ) { queryIds = new LocalIdCollection( ); // // Special case LocalId. This means // that the exact row id is known, so // just add all caontained ids to the list. // if( "localid" == q.IndexName.ToLower( System.Globalization.CultureInfo.InvariantCulture ) ) { for( int i = 0; i < q.Count; i++ ) { for( int j = 0; j < q[ i ].ObjectList.Length; j++ ) { Int32 value = Convert.ToInt32( q[ i ].ObjectList[ j ], System.Globalization.NumberFormatInfo.InvariantInfo ) ; queryIds.Add( value ); } } } else { // // Perform a match agains the currently collected // Ids and the current query, if false, no results // matched. // if( !SingleMatch( q, queryIds ) ) { // // If we had a failed match, // ensure that the list of ids is cleared. // if( null != localIds ) { localIds.Clear( ); } break; } } // // Perform the AND between the current // results, and the returned results. // if( null == localIds ) { localIds = queryIds; } else { localIds.Filter( queryIds ); } IDT.TraceDebug( "STORE: {0} matches found for index {1}", queryIds.Count, q.IndexName ); IDT.TraceDebug( "STORE: {0} unique matches found as of current", null != localIds ? localIds.Count : 0 ); } } finally { if (lockHeld) { m_lock.ReleaseReaderLock( ); } } IDT.TraceDebug( "STORE: Search Results: {0} item(s) found.", null != localIds ? localIds.Count : 0 ); IDT.TraceDebug( "STORE: Search Process Complete on {0}", SourceId ); // // If we didn't have any local ids, // then just bail. // if( null == localIds || 0 == localIds.Count ) { IDT.TraceDebug( "STORE: Query Complete, 0 DataRow(s) returned." ); return null; } IDT.TraceDebug( "STORE: Begining DataCollection Process on {0}", SourceId ); rows = new List ( localIds.Count ); foreach( int id in localIds.Keys ) { IDT.TraceDebug( "STORE: Collecting data for objectId {0}", id ); // // If a detail level of identifiers is specified, // we don't have to read the row from the data // buffer, we have all of the information we need. // if( QueryDetails.Identifiers == details ) { DataRow row = new DataRow(); row.LocalId = id; row.SourceId = SourceId; row.InstanceId = InstanceId; rows.Add( row ); } else { // // Read the details of the row from the data source. // rows.Add( ReadRow( id,details ) ); } } IDT.TraceDebug( "STORE: DataCollection Process Complete on {0}", SourceId ); IDT.TraceDebug( "STORE: Query Complete, {0} DataRow(s) returned.", localIds.Count ); return rows; } // // Summary: // Saves a DataRow to this data source. // // Remarks: // if the row has a SourceId and InstanceId set, // it must be the same as the local values. // // This method also updates the LastChange value on the row. // // Paramters: // row: The data row you would like to save. (see remarks) // public void Save( DataRow row ) { ThrowIfDisposed( ); ThrowIfNotLoaded( ); ThrowIfWriteLockNotHeld( ); if( null == row ) { throw IDT.ThrowHelperArgumentNull( "row" ); } // // If either of these are set, // they must both must match our source info // if( !String.IsNullOrEmpty( row.InstanceId ) || !String.IsNullOrEmpty( row.SourceId ) ) { // // Note Ordinal will compare the bytes as they are. // This is especially interesting for Unicode Chars. // So though the following mean the same linguistically, they will be interpreted as different. // string separated = "\u0061\u030a"; //latin small letter 'a' & ring above // string combined = "\u00e5"; //latin small letter 'a' with ring above // [ Using Invariant Culture as opposed Ordinal to will match these. ] // if( 0 != string.Compare( row.InstanceId, InstanceId, StringComparison.Ordinal ) || 0 != string.Compare( row.SourceId, SourceId, StringComparison.Ordinal ) ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.StoreRowOwnedByOtherDataSource ) ) ); } } IDT.TraceDebug( "STORE: Begining Save Operation on {0}", SourceId ); row.LastChange = DateTime.Now.ToFileTimeUtc(); // // Call the implementers WriteRow // WriteRow( row ); row.InstanceId = InstanceId; row.SourceId = SourceId; IDT.TraceDebug( "STORE: Save Operation Complete on {0}", SourceId ); } // // Summary: // Deletes a datarow from the data source. // // Remarks: // InstanceId and SourceId must be set to the current members. // // Parameters: // row: The row you would like to delete. // public void Delete( DataRow row ) { ThrowIfDisposed( ); ThrowIfNotLoaded( ); ThrowIfWriteLockNotHeld( ); if( null == row ) { throw IDT.ThrowHelperArgumentNull( "row" ); } // // If either of these are set, // they must both must match our source info // if( null == row.InstanceId || null == row.SourceId ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.StoreDataSourceRowNotOwned ) ) ); } // // Note Ordinal will compare the bytes as they are. // This is especially interesting for Unicode Chars. // So though the following mean the same linguistically, they will be interpreted as different. // string separated = "\u0061\u030a"; //latin small letter 'a' & ring above // string combined = "\u00e5"; //latin small letter 'a' with ring above // [ Using Invariant Culture as opposed Ordinal to will match these. ] // if( 0 != string.Compare( row.InstanceId, InstanceId, StringComparison.Ordinal ) || 0 != string.Compare( row.SourceId, SourceId, StringComparison.Ordinal ) ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.StoreRowOwnedByOtherDataSource ) ) ); } IDT.TraceDebug( "STORE: Begining Delete Operation on {0}", SourceId ); // // Call Implementers RemoveObject // RemoveObject( row.LocalId ); IDT.TraceDebug( "STORE: Delete Operation Complete on {0}", SourceId ); } // // Summary: // Tests a specified QueryDetails value for correctness. // // Remarks: // // Valid Combos: // // Flags. Combos // ------------ --------------------- // Identifiers 1 1 1 1 0 // Header 1 1 1 0 0 // DataBlob 1 1 0 0 0 // IndexData 1 0 0 0 0 // // Parameters: // details: The QueryDetails value to test. // // Returns: // boolean indicated that the value is valid. // protected internal virtual bool IsValidQueryDetails( QueryDetails details ) { if( QueryDetails.IndexData == ( details & QueryDetails.IndexData ) ) { return QueryDetails.FullRowAndIndexes == ( details & QueryDetails.FullRowAndIndexes ); } else if( QueryDetails.DataBlob == ( details & QueryDetails.DataBlob ) ) { return QueryDetails.FullRow == ( details & QueryDetails.FullRow ); } else if( QueryDetails.Header == ( details & QueryDetails.Header ) ) { return QueryDetails.FullHeader == ( details & QueryDetails.FullHeader); } else if( QueryDetails.Identifiers == ( details & QueryDetails.Identifiers ) ) { return QueryDetails.Identifiers == ( details & QueryDetails.Identifiers ); } else { return ( QueryDetails.None == details ); } } protected internal virtual void OnBeginTransaction() { ThrowIfDisposed( ); } protected internal virtual void OnCommitTransaction() { ThrowIfDisposed( ); } protected internal virtual void OnRollbackTransaction() { ThrowIfDisposed( ); } protected internal virtual void OnLoad() { ThrowIfDisposed( ); } protected internal virtual void OnClose() { ThrowIfDisposed( ); } protected internal virtual void OnClear() { ThrowIfDisposed(); } protected internal virtual void OnDispose() { } protected internal abstract void WriteRow( DataRow row ); protected internal abstract void RemoveObject( Int32 id ); protected internal abstract DataRow ReadRow( Int32 localId,QueryDetails details ); protected internal abstract bool SingleMatch( QueryParameter match, LocalIdCollection localIds ); void IDisposable.Dispose() { OnDispose( ); m_isDisposed = true; } protected internal void ThrowIfWriteLockNotHeld() { if( !m_lock.IsWriterLockHeld ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.StoreDataSourceWriteLockNotHeld ) ) ); } } protected internal void ThrowIfWriteLockHeld() { if( m_lock.IsWriterLockHeld ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.StoreProcessingTransaction ) ) ); } } protected internal void ThrowIfNotLoaded() { if( !m_isLoaded ) { throw IDT.ThrowHelperError( new ObjectDisposedException( "DataSource" ) ); } } protected internal void ThrowIfLoaded() { if( m_isLoaded ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.StoreIsAlreadyLoaded ) ) ); } } protected internal void ThrowIfDisposed() { if( m_isDisposed ) { throw IDT.ThrowHelperError( new ObjectDisposedException( "DataSource" ) ); } } // // Summary: Build a QueryParamter for the ix_objecttype index, that contains all // of the values other than unknown. This is used in the deletion of all // the relevant store data. UserPreference is left in the store to preserve // the UI size related information (will be shortly). // public static QueryParameter CreateDeleteStoreTypeQuery() { QueryParameter deleteStoreQuery = new QueryParameter( SecondaryIndexDefinition.ObjectTypeIndex ); Array objectTypes = Enum.GetValues( typeof( StorableObjectType ) ); foreach( Int32 type in objectTypes ) { if ( (Int32) StorableObjectType.Unknown != type ) { deleteStoreQuery.AddMatch( type ); } } return deleteStoreQuery; } } internal delegate int MergeConflictCallback( DataRow local, DataRow incomingData ); } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ValidatingReaderNodeData.cs
- ComplexPropertyEntry.cs
- MatcherBuilder.cs
- DbConnectionPoolCounters.cs
- IgnoreSection.cs
- _AutoWebProxyScriptWrapper.cs
- HttpRequest.cs
- smtppermission.cs
- SqlBulkCopyColumnMappingCollection.cs
- TextEditorSelection.cs
- RepeaterCommandEventArgs.cs
- UDPClient.cs
- AppDomainUnloadedException.cs
- QueueException.cs
- CommonDialog.cs
- ConfigurationSectionGroup.cs
- CompilerLocalReference.cs
- ErrorTableItemStyle.cs
- WrapPanel.cs
- SiteMapDataSource.cs
- AddInPipelineAttributes.cs
- XPathNavigatorKeyComparer.cs
- CustomErrorCollection.cs
- SQLUtility.cs
- GenericRootAutomationPeer.cs
- ColumnBinding.cs
- ProgressChangedEventArgs.cs
- SymbolUsageManager.cs
- IntegerValidator.cs
- LineVisual.cs
- ControllableStoryboardAction.cs
- ZoneLinkButton.cs
- TranslateTransform.cs
- sapiproxy.cs
- DataGridViewDataErrorEventArgs.cs
- ManifestResourceInfo.cs
- RequestNavigateEventArgs.cs
- TreePrinter.cs
- XmlSchemaAttribute.cs
- CorrelationToken.cs
- InfoCardRSACryptoProvider.cs
- RadioButton.cs
- ColorBlend.cs
- XmlSchemaProviderAttribute.cs
- IImplicitResourceProvider.cs
- ToggleProviderWrapper.cs
- InputQueue.cs
- XsdDateTime.cs
- RangeBaseAutomationPeer.cs
- SoapAttributeAttribute.cs
- CallbackHandler.cs
- Point3DAnimationUsingKeyFrames.cs
- BaseAutoFormat.cs
- SafeTimerHandle.cs
- ComplexBindingPropertiesAttribute.cs
- RefreshEventArgs.cs
- AssemblyGen.cs
- Graphics.cs
- ValidatorCollection.cs
- SafeViewOfFileHandle.cs
- StringReader.cs
- TextParentUndoUnit.cs
- InputReferenceExpression.cs
- FileSystemEventArgs.cs
- BehaviorEditorPart.cs
- GridViewDeletedEventArgs.cs
- SchemaLookupTable.cs
- DynamicArgumentDialog.cs
- WebBrowsableAttribute.cs
- QilName.cs
- EncoderParameters.cs
- OlePropertyStructs.cs
- ComPlusDiagnosticTraceSchemas.cs
- InvalidCastException.cs
- ObjectTag.cs
- RSACryptoServiceProvider.cs
- FloaterParagraph.cs
- EnumBuilder.cs
- _NestedSingleAsyncResult.cs
- HtmlImage.cs
- DirectoryRedirect.cs
- _AutoWebProxyScriptEngine.cs
- _ConnectionGroup.cs
- ParameterBuilder.cs
- SrgsOneOf.cs
- ObjectDataSourceStatusEventArgs.cs
- ListSourceHelper.cs
- WebExceptionStatus.cs
- EventSetter.cs
- CustomSignedXml.cs
- XmlMapping.cs
- XmlILConstructAnalyzer.cs
- FontWeightConverter.cs
- DotAtomReader.cs
- SymLanguageVendor.cs
- listitem.cs
- _SslState.cs
- Substitution.cs
- XmlNavigatorStack.cs
- IPipelineRuntime.cs