示例#1
0
        /// <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.");
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
                }
            }
        }
示例#4
0
        public bool TryRemove(ObjectIdType objectId)
        {
            List <ExKeyT> toBeRemoved = _children.Keys.Where(x => x.Level1Key == objectId).ToList();

            bool result = TryRemove(toBeRemoved);

            return(result);
        }
示例#5
0
        public ObjectIdType Explode(CompositeKeyType cKey, out PropIdType bot)
        {
            bot = (PropIdType)(cKey & _botMask);

            ObjectIdType result = (cKey >> _botFieldLen) & _topMask;

            return(result);
        }
示例#6
0
        //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);
        }
示例#9
0
        /// <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);
        }
示例#10
0
        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);
        }
示例#13
0
        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);
        }
示例#15
0
        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;
        }
示例#18
0
        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");
        }
示例#19
0
        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;
                }
            }
        }
示例#20
0
 public BagNode(ObjectIdType objectId, IPropBag propBag, int maxPropsPerObject, ICacheDelegates <CallPSParentNodeChangedEventSubDelegate> callPSParentNodeChangedEventSubsCache)
     : this(objectId, propBag, null, maxPropsPerObject, callPSParentNodeChangedEventSubsCache)
 {
 }
示例#21
0
        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));
        }
示例#22
0
        //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))
        {
        }
示例#23
0
        public bool Verify(CompositeKeyType cKey, ObjectIdType top, PropIdType bot)
        {
            ObjectIdType testTop = Explode(cKey, out PropIdType testBot);

            return(testTop == top && testBot == bot);
        }
示例#24
0
        public bool Verify(CompositeKeyType cKey, ObjectIdType top)
        {
            ObjectIdType testTop = (cKey >> _botFieldLen) & _topMask;

            return(testTop == top);
        }
示例#25
0
        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));
        }