/// <summary> /// Creates a new BagNode for the specified PropBag, optionally using a collection of PropNodes as the source. /// The source PropNodes are cloned. If the value of a PropNode cannot be cloned, an InvalidOperation exception will be thrown. /// This is the core of IPropBag.Clone() /// </summary> /// <param name="objectId">The new globally unique Id to use for this new BagNode.</param> /// <param name="propBag">The client IPropBag.</param> /// <param name="template">A Collection of PropNodes to use as a template for the new PropBag's Child PropItems. Can be null.</param> /// <param name="maxPropsPerObject">The maximum number of PropItems a single PropBag can have.</param> /// <param name="callPSParentNodeChangedEventSubsCache">A reference to a service that caches Parent Node Change Event dispatchers.</param> public BagNode(ObjectIdType objectId, IPropBag propBag, PropNodeCollectionIntInterface template, int maxPropsPerObject, ICacheDelegates <CallPSParentNodeChangedEventSubDelegate> callPSParentNodeChangedEventSubsCache) { CompKey = new SimpleExKey(objectId, 0); PropBagProxy = new WeakRefKey <IPropBag>(propBag ?? throw new ArgumentNullException(nameof(propBag))); _callPSParentNodeChangedEventSubsCache = callPSParentNodeChangedEventSubsCache ?? throw new ArgumentNullException(nameof(callPSParentNodeChangedEventSubsCache)); _parentNCSubscriberCollection = null; if (template == null) { _propNodeCollection = new PropNodeCollection(maxPropsPerObject); } else { _propNodeCollection = ClonePropNodes(template, this); //var x = EqualityComparer<WeakRefKey<PropModelType>?>.Default; //bool propItemSetIdsMatch = x.Equals(_propNodeCollection.PropItemSetId, template.PropItemSetId); //System.Diagnostics.Debug.Assert(EqualityComparer<WeakRefKey<PropModelType>?>.Default.Equals(_propNodeCollection.PropItemSetId, template.PropItemSetId), "PropItemSetIds don't match."); bool propItemSetIdsMatch = _propNodeCollection.PropItemSetKey == template.PropItemSetKey; System.Diagnostics.Debug.Assert(propItemSetIdsMatch, "PropItemSetIds don't match."); System.Diagnostics.Debug.Assert(_propNodeCollection.IsFixed == template.IsFixed, "IsFixed doesn't match."); } }
public PSAccessServiceInterface CreatePropStoreService(IPropBag propBag, PropNodeCollectionInternalInterface propNodes, out BagNode newBagNode) { // Issue a new, unique Id for this propBag. ObjectIdType objectId = NextObjectId; // Create a new PropStoreNode for this PropBag newBagNode = new BagNode(objectId, propBag, propNodes, MaxPropsPerObject, _handlerDispatchDelegateCacheProvider.CallPSParentNodeChangedEventSubsCache); WeakRefKey <IPropBag> propBagProxy = newBagNode.PropBagProxy; lock (_sync) { // Add the node to the global store. _store.Add(propBagProxy, newBagNode); // If the PropNodeCollection is fixed, update our Store By Type (for fast lookups.) if (newBagNode.PropNodeCollection.IsFixed) { AddFixedPropCollection(newBagNode.PropNodeCollection); } } // Create the access service. PSAccessServiceInterface result = new SimplePropStoreAccessService ( newBagNode, this, _handlerDispatchDelegateCacheProvider ); // Add one more to the total count of PropStoreAccessServices created. IncAccessServicesCreated(); return(result); }
private bool RemoveFixedPropCollection(ObjectIdType objectId, PropNodeCollectionInternalInterface pnc) { if (pnc.Count == 0) { return(true); } PropItemSetKeyType propItemSetKey = pnc.PropItemSetKey; lock (_syncForByTypeStore) { if (!TryGetSharedPropCollection(propItemSetKey, out PropNodelCollectionSharedInterface sharedPropNodeCollection)) { throw new InvalidOperationException($"Could not retrieve the SharedPropCollection for {propItemSetKey.FullClassName} while removing {pnc}."); } if (sharedPropNodeCollection.TryRemove(objectId)) { if (sharedPropNodeCollection.Count == 0) { _storeByType.Remove(pnc.PropItemSetKey); } return(true); } else { System.Diagnostics.Debug.WriteLine($"Could not remove {pnc} from {sharedPropNodeCollection}."); return(false); } } }
public bool TryRemove(ObjectIdType objectId) { List <ExKeyT> toBeRemoved = _children.Keys.Where(x => x.Level1Key == objectId).ToList(); bool result = TryRemove(toBeRemoved); return(result); }
public ObjectIdType Explode(CompositeKeyType cKey, out PropIdType bot) { bot = (PropIdType)(cKey & _botMask); ObjectIdType result = (cKey >> _botFieldLen) & _topMask; return(result); }
//public object AccessToken => WR_AccessToken; //public WeakReference<IPropBagInternal> WR_AccessToken { get; } #endregion #region Public Methods public CompositeKeyType Fuse(ObjectIdType top, PropIdType bot) { CompositeKeyType result = top; result = result << _botFieldLen; result += bot; return(result); }
SimpleExKey GetCompKey(IPropBag propBag, PropIdType propId) { ObjectIdType objectId = GetAndCheckObjectRef(propBag); CompositeKeyType cKey = _compKeyManager.JoinComp(objectId, propId); SimpleExKey exKey = new SimpleExKey(cKey, _clientAccessToken, objectId, propId); return(exKey); }
public IEnumerable <IPropGen> GetValues(IPropBag propBag) { ObjectIdType objectId = GetAndCheckObjectRef(propBag); IEnumerable <KeyValuePair <SimpleExKey, IPropGen> > propDataObjectsForThisPropBag = _theGlobalStore.Where(x => x.Key.Level1Key == objectId); IEnumerable <IPropGen> result = propDataObjectsForThisPropBag.Select(x => x.Value); return(result); }
/// <summary> /// Assumes that propNodes contains a complete set of child PropNodes for a particular BagNode and may or may not contain /// propNodes from other BagNodes. (Sharing the same PropItemSetKey, of course.) /// </summary> /// <returns></returns> private Dictionary <PropNameType, PropIdType> BuildByNameDict() { ObjectIdType objectId = _children.Keys.First()?.Level1Key ?? (UInt64)0; var repFam = _children.Where(x => x.Key.Level1Key == objectId); Dictionary <PropNameType, PropIdType> result = repFam.ToDictionary(k => k.Value.PropertyName, v => v.Value.PropId); return(result); }
public async Task EnsureTableAsync(NsDatabase database, string tableName, ObjectIdType objectIdType = ObjectIdType.Guid) { Validate.NotNull(database, nameof(database)); Validate.NotNullOrEmptyOrWhiteSpace(tableName, nameof(tableName)); await ExecuteNonQueryAsync( $"CREATE TABLE IF NOT EXISTS \"{database.Name}\".\"{tableName}\"(" + (objectIdType == ObjectIdType.Guid ? $"_id UUID" : "BIGSERIAL") + " PRIMARY KEY," + $"_document TEXT NOT NULL)"); }
// TODO: Consider keeping a index of all Props, // or making the caller remove each Prop individually. public void Clear(IPropBag propBag) { ObjectIdType objectId = GetAndCheckObjectRef(propBag); IEnumerable <KeyValuePair <SimpleExKey, IPropGen> > propDataObjectsForThisPropBag = _theGlobalStore.Where(x => x.Key.Level1Key == objectId); foreach (KeyValuePair <SimpleExKey, IPropGen> kvp in propDataObjectsForThisPropBag) { _theGlobalStore.TryRemove(kvp.Key, out IPropGen dontNeedItVal); } }
public IEnumerable <KeyValuePair <PropNameType, IPropGen> > GetCollection(IPropBag propBag) { ObjectIdType objectId = GetAndCheckObjectRef(propBag); IEnumerable <KeyValuePair <SimpleExKey, IPropGen> > propDataObjectsForThisPropBag = _theGlobalStore.Where(x => x.Key.Level1Key == objectId); IEnumerable <KeyValuePair <PropNameType, IPropGen> > result = propDataObjectsForThisPropBag.Select(x => new KeyValuePair <PropNameType, IPropGen>(GetPropNameFromL2Key(x.Key.Level2Key), x.Value)); return(result); }
public bool Contains(ObjectIdType objectId) { foreach (KeyValuePair <ExKeyT, PropNode> kvp in _children) { if (kvp.Key.Level1Key == objectId) { return(true); } } return(false); }
ObjectIdType GetAndCheckObjectRef(IPropBag propBag) { IPropBag client = SimpleExKey.UnwrapWeakRef(_clientAccessToken); if (!object.ReferenceEquals(propBag, client)) { throw new InvalidOperationException("This PropStoreAccessService can only service the PropBag object that created it."); } ObjectIdType result = _objectId; return(result); }
public bool TryGetPropNodeCollection(ObjectIdType objectId, out PropNodeCollectionIntInterface propNodeCollection) { IEnumerable <PropNode> family = _children.Where(kvp => kvp.Key.Level1Key == objectId).Select(x => x.Value); if (family.FirstOrDefault() != null) { propNodeCollection = new PropNodeCollectionFixed(family, _propItemSetKey, MaxPropsPerObject); return(true); } else { propNodeCollection = null; return(false); } }
//public SubscriberCollection GetSubscriptions(IPropBag host, PropIdType propId, SimplePropStoreAccessService storeAccessor) //{ // SimpleExKey exKey = GetTheKey(host, propId, storeAccessor); // SubscriberCollection result = GetSubscriptions(exKey); // return result; //} //public SubscriberCollection GetSubscriptions(IPropBag host, PropIdType propId, PSAccessServiceInterface storeAccessor) //{ // SimpleExKey exKey = GetTheKey(host, propId, storeAccessor); // SubscriberCollection result = GetSubscriptions(exKey); // return result; //} //private SimpleExKey GetTheKey(IPropBag host, uint propId, SimplePropStoreAccessService storeAccessor) //{ // SimpleExKey result = ((IHaveTheSimpleKey)storeAccessor).GetTheKey(host, propId); // return result; //} //private SimpleExKey GetTheKey(IPropBag host, uint propId, PSAccessServiceInterface storeAccessor) //{ // ExKeyType exKey = ((HaveTheKeyType) storeAccessor).GetTheKey(host, propId); // SimpleExKey withWeakRef = SimpleExKey.FromIExploadedKeyWithWeakRef(exKey); // return withWeakRef; //} #endregion #region Private Methods private CollectionOfSubscriberCollections GetPropIndexForObject(ObjectIdType objectKey, out bool wasAdded) { bool internalWasAdded = false; CollectionOfSubscriberCollections result = _propIndexesByObject.GetOrAdd ( key: objectKey, valueFactory: ( x => { internalWasAdded = true; return(new CollectionOfSubscriberCollections()); } ) ); wasAdded = internalWasAdded; return(result); }
//SimpleObjectExIdDictionary _theGlobalStore; //IReadOnlyDictionary<ObjectRefType, ObjectIdType> _objectIdDictionary; #endregion #region Constructor public SimplePropStoreAccessServiceWithExKey ( WeakReference <IPropBag> clientAccessToken, ObjectIdType objectId, SimpleObjectExIdDictionary theGlobalStore, SimpleExCompKeyMan compKeyManager, SimpleLevel2KeyMan level2KeyManager ) { _clientAccessToken = clientAccessToken; _objectId = objectId; _theGlobalStore = theGlobalStore; _compKeyManager = compKeyManager; _level2KeyManager = level2KeyManager; MaxPropsPerObject = compKeyManager.MaxPropsPerObject; MaxObjectsPerAppDomain = compKeyManager.MaxObjectsPerAppDomain; }
public async Task EnsureTableAsync(NsDatabase database, string tableName, ObjectIdType objectIdType = ObjectIdType.Guid) { Validate.NotNull(database, nameof(database)); Validate.NotNullOrEmptyOrWhiteSpace(tableName, nameof(tableName)); await ExecuteNonQueryAsync( $"USE [{database.Name}]", $"IF NOT EXISTS (select * from sysobjects where name='{tableName}' and xtype='U')", $"BEGIN", $"CREATE TABLE [dbo].[{tableName}](", objectIdType == ObjectIdType.Guid? "[_id] [uniqueidentifier] NOT NULL," : "[_id] [int] IDENTITY(1,1) NOT NULL", $"[_document] [nvarchar](max) NOT NULL,", $"CONSTRAINT [PK_{tableName}] PRIMARY KEY CLUSTERED ", $"(", $"[_id] ASC", $") WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]", $") ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]", objectIdType == ObjectIdType.Guid?$"ALTER TABLE [dbo].[{tableName}] ADD CONSTRAINT [DF_{tableName}__id] DEFAULT (newid()) FOR [_id]" : string.Empty, $"END"); }
private void ReflectModelType() { if (_typeReflector != null) { return; } _typeReflector = TypeReflector.Create <T>(); var idKey = _typeReflector.Properties.FirstOrDefault(_ => StringComparer.OrdinalIgnoreCase.Compare(_.Key, "id") == 0); if (idKey.Key == null) { idKey = _typeReflector.Properties.FirstOrDefault(_ => StringComparer.OrdinalIgnoreCase.Compare(_.Key, "uniqueid") == 0); } if (idKey.Key == null) { idKey = _typeReflector.Properties.FirstOrDefault(_ => StringComparer.OrdinalIgnoreCase.Compare(_.Key, "objectid") == 0); } if (idKey.Key != null && _typeReflector.Properties[idKey.Key].PropertyType != typeof(int) && _typeReflector.Properties[idKey.Key].PropertyType != typeof(Guid)) { throw new InvalidOperationException("Id property must be of type Guid or Int32"); } _idPropertyName = idKey.Key; if (_idPropertyName != null) { if (_typeReflector.Properties[_idPropertyName].PropertyType == typeof(int)) { _typeOfObjectId = ObjectIdType.Int; } } }
public BagNode(ObjectIdType objectId, IPropBag propBag, int maxPropsPerObject, ICacheDelegates <CallPSParentNodeChangedEventSubDelegate> callPSParentNodeChangedEventSubsCache) : this(objectId, propBag, null, maxPropsPerObject, callPSParentNodeChangedEventSubsCache) { }
public async Task <object> InsertAsync(NsDatabase database, string tableName, string json, object id, ObjectIdType typeOfObjectId) { Validate.NotNull(database, nameof(database)); Validate.NotNullOrEmptyOrWhiteSpace(tableName, nameof(tableName)); Validate.NotNull(json, nameof(json)); if (id != null) { await ExecuteNonQueryAsync(new[] { $"USE [{database.Name}]", $"INSERT INTO [dbo].[{tableName}]", $" ([_id]", $" ,[_document])", $" VALUES", $" (@id", $" ,@document)", $"SELECT SCOPE_IDENTITY();" }, new Dictionary <string, object>() { { "@id", id }, { "@document", json } }, executeAsScalar : false); return(id); } return(await ExecuteNonQueryAsync(new[] { $"USE [{database.Name}]", $"INSERT INTO [dbo].[{tableName}]", $" ([_document])" + $"output INSERTED._id", $" VALUES", $" (@document)" }, new Dictionary <string, object>() { { "@document", json } }, executeAsScalar : true)); }
//static SimpleExKey() //{ // int numBitsForProps = LOG_BASE2_MAX_PROPERTIES; // int numberOfBitsInCKey = (int)Math.Log(CompositeKeyType.MaxValue, 2); // int numberOfTopBits = numberOfBitsInCKey - numBitsForProps; // _maxObjectsPerAppDomain = (long)Math.Pow(2, numberOfTopBits); // _shift = numberOfTopBits; // _botFieldLen = numBitsForProps; // numberOfBitsInCKey - numberOfTopBits; // _botMask = ((CompositeKeyType)1 << _botFieldLen) - 1; // _topMask = ((CompositeKeyType)1 << numberOfTopBits) - 1; //} #region Constructor //public SimpleExKey(CompositeKeyType cKey/*, WeakReference<IPropBagInternal> accessToken, ObjectIdType level1Key, PropIdType level2Key*/) : this() //{ // CKey = cKey; // Level1Key = level1Key; // Level2Key = level2Key; // //WR_AccessToken = accessToken ?? throw new ArgumentNullException(nameof(accessToken)); //} public SimpleExKey(ObjectIdType level1Key, PropIdType level2Key) : this(StaticFuse(level1Key, level2Key)) { }
public bool Verify(CompositeKeyType cKey, ObjectIdType top, PropIdType bot) { ObjectIdType testTop = Explode(cKey, out PropIdType testBot); return(testTop == top && testBot == bot); }
public bool Verify(CompositeKeyType cKey, ObjectIdType top) { ObjectIdType testTop = (cKey >> _botFieldLen) & _topMask; return(testTop == top); }
public async Task <object> InsertAsync(NsDatabase database, string tableName, string json, object id, ObjectIdType typeOfObjectId) { Validate.NotNull(database, nameof(database)); Validate.NotNullOrEmptyOrWhiteSpace(tableName, nameof(tableName)); Validate.NotNull(json, nameof(json)); if (id != null || typeOfObjectId == ObjectIdType.Guid) { await ExecuteNonQueryAsync(new[] { $"INSERT INTO \"{database.Name}\".\"{tableName}\"", $" (\"_id\"", $" ,\"_document\")", $" VALUES", $" (@id", $" ,@document)" }, new Dictionary <string, object>() { { "@id", id ?? Guid.NewGuid() }, { "@document", json } }, executeAsScalar : false); return(id); } return(await ExecuteNonQueryAsync(new[] { $"INSERT INTO \"{database.Name}\".\"{tableName}\"", $" (\"_document\")" + $" VALUES", $" (@document)", $"RETURNING _id" }, new Dictionary <string, object>() { { "@document", json } }, executeAsScalar : true)); }