Esempio n. 1
0
        private async Task <PersonDetailCollectionResult> GetDetailByArgsOnImplementationAsync(PersonArgs args, PagingArgs paging)
        {
            var pdcr = new PersonDetailCollectionResult(new PagingResult(paging));

            await _db.StoredProcedure("[Demo].[spPersonGetDetailByArgs]")
            .Params(p =>
            {
                p.ParamWithWildcard(args?.FirstName, DbMapper.Default[nameof(Person.FirstName)])
                .ParamWithWildcard(args?.LastName, DbMapper.Default[nameof(Person.LastName)])
                .TableValuedParamWith(args?.Genders, "GenderIds", () => TableValuedParameter.Create(args.Genders.ToGuidIdList()));
            })
            .SelectQueryMultiSetAsync(pdcr.Paging,
                                      new MultiSetCollArgs <PersonCollection, Person>(PersonData.DbMapper.Default, (r) => r.ForEach((p) => { var pd = new PersonDetail(); pd.CopyFrom(p); pdcr.Result.Add(pd); })),
                                      new MultiSetCollArgs <WorkHistoryCollection, WorkHistory>(WorkHistoryData.DbMapper.Default, (r) =>
            {
                PersonDetail pd = null;
                foreach (var wh in r)
                {
                    if (pd == null || wh.PersonId != pd.Id)
                    {
                        pd         = pdcr.Result.Where(x => x.Id == wh.PersonId).Single();
                        pd.History = new WorkHistoryCollection();
                    }

                    pd.History.Add(wh);
                }
            }));

            return(pdcr);
        }
Esempio n. 2
0
        /// <summary>
        ///     Adds the shallow clone.
        /// </summary>
        /// <param name="sourceId">The source identifier.</param>
        /// <param name="destinationId">The destination identifier.</param>
        public void AddShallowClone(long sourceId, long destinationId)
        {
            DataTable dt;

            if (!EntityClones.TryGetValue(CloneOption.Shallow, out dt))
            {
                dt = TableValuedParameter.Create(TableValuedParameterType.EntityMap);
                EntityClones[CloneOption.Shallow] = dt;
            }

            dt.Rows.Add(sourceId, destinationId);
        }
        /// <summary>
        /// Prepare the SQL to load in all values of all fields in the entity request.
        /// </summary>
        private void ProcessFields( )
        {
            ISet <IEntityRef> fields = new HashSet <IEntityRef>( );

            foreach (var v in _requestNodeMap.Values)
            {
                fields.UnionWith(v.Request.Fields);
            }

            // Cache whether the fields are virtual
            BulkRequestHelper.IsVirtualField(fields);

            // Creates a lookup, that for each type of table contains a list of tuples,
            // with each tuple matching node tags to fields that need to be loaded for that node tag.
            ILookup <string, Tuple <int, long> > fieldMap =
                (from nodeInfo in _requestNodeMap.Values
                 from field in nodeInfo.Request.Fields
                 let fieldInfo = RegisterFieldInfo(field)
                                 where !(fieldInfo.IsVirtualAccessControlField || fieldInfo.IsCalculated)
                                 select new Tuple <int, long>(nodeInfo.Tag, field.Id)
                ).ToLookup(MapTagAndFieldPairToTableName);

            // Create sql
            foreach (var list in fieldMap)
            {
                string tableName = list.Key;

                // Frustrate injection attack.
                if (!(tableName.StartsWith("Data_") && tableName.Length < 15))
                {
                    throw new InvalidOperationException("Field type table name was invalid: " + tableName);
                }

                DataTable dt  = TableValuedParameter.Create(TableValuedParameterType.BulkFldType);
                var       map = new HashSet <Tuple <int, long> >( );

                foreach (Tuple <int, long> entry in list)
                {
                    if (map.Contains(entry))
                    {
                        continue;
                    }

                    map.Add(entry);
                    dt.Rows.Add(entry.Item1, entry.Item2);
                }

                string tvpName = "@fld" + tableName;

                _result.TableValuedParameters [tvpName] = dt;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Populate the input entities datatable.
        /// </summary>
        private void PopulateInputEntitiesTable()
        {
            if (Entities == null || Entities.Count == 0)
            {
                return;
            }

            _inputEntitiesTable = TableValuedParameter.Create(TableValuedParameterType.InputEntityType);

            foreach (IEntity entity in Entities.Values)
            {
                if (entity.IsReadOnly)
                {
                    Mapping[entity.Id] = entity.Id;
                    continue;
                }

                var entityInternal = entity as IEntityInternal;

                if (entityInternal == null)
                {
                    continue;
                }

                if (entityInternal.IsTemporaryId)
                {
                    bool foundType = false;

                    int isClone = entityInternal.CloneSource == null ? 0 : 1;

                    foreach (long typeId in entity.TypeIds)
                    {
                        _inputEntitiesTable.Rows.Add(entity.Id, typeId, isClone);
                        foundType = true;
                    }

                    if (!foundType)
                    {
                        _inputEntitiesTable.Rows.Add(entity.Id, -1L, isClone);
                    }
                }
                else
                {
                    Mapping[entity.Id] = entity.Id;
                }
            }
        }
Esempio n. 5
0
        public HttpResponseMessage <IDictionary <long, Guid> > GetUpgradeIdsByEntityIds([FromBody] List <long> entityIds)
        {
            if (entityIds == null)
            {
                throw new WebArgumentNullException("entityIds");
            }

            IDictionary <long, Guid> dict = new Dictionary <long, Guid>();
            DataTable dt = TableValuedParameter.Create(TableValuedParameterType.BigInt);

            foreach (var entityId in entityIds)
            {
                dt.Rows.Add(entityId);
            }

            using (DatabaseContext context = DatabaseContext.GetContext(false))
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                using (IDbCommand command = context.CreateCommand())
                {
                    command.CommandText = "dbo.spGetUpgradeIdsByEntityIds";
                    command.CommandType = CommandType.StoredProcedure;
                    command.AddParameter("@tenantId", DbType.Int64, EDC.ReadiNow.IO.RequestContext.TenantId);
                    command.AddTableValuedParameter("@data", dt);

                    using (IDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var id   = reader.GetInt64(0);
                            var guid = reader.GetGuid(1);

                            dict[id] = guid;
                        }
                    }
                }
            }

            return(new HttpResponseMessage <IDictionary <long, Guid> >(dict, HttpStatusCode.OK));
        }
Esempio n. 6
0
 private void GetByArgsOnQuery(DatabaseParameters p, PersonArgs args, IDatabaseArgs dbArgs)
 {
     p.ParamWithWildcard(args?.FirstName, DbMapper.Default[nameof(Person.FirstName)])
     .ParamWithWildcard(args?.LastName, DbMapper.Default[nameof(Person.LastName)])
     .TableValuedParamWith(args?.Genders, "GenderIds", () => TableValuedParameter.Create(args.Genders.ToGuidIdList()));
 }
Esempio n. 7
0
        /// <summary>
        /// Gets the entities that should not be removed as part of an upgrade operation.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public IEnumerable <Guid> GetDoNotRemove(IProcessingContext context)
        {
            // Namely, get the entities that:
            // 1. used to be part of the application,
            // 2. which are no longer part of the application,
            // 3. which are still present in the tenant (i.e. the app developer removed them from the app, but didn't delete them altogether).
            // 4. we also need to carry over any entities marked as 'do not remove' in previous versions

            // Step 0: Determine what the original version of this package was
            Guid?packageId = OriginalPackageId;

            if (packageId == null)
            {
                context.WriteInfo("Tenant application does not have a package Id");
                return(Enumerable.Empty <Guid>( ));
            }

            // Step 1: Get entities in the previous version
            LibraryAppSource appLibrarySource = new LibraryAppSource
            {
                AppVerId = packageId.Value
            };
            IEnumerable <Guid> entitiesInPrevVersion = appLibrarySource
                                                       .GetEntities(context)
                                                       .Select(e => e.EntityId)
                                                       .ToList( );

            // Step 2: Disregard entities that are still in the application
            IEnumerable <Guid> entitiesInTenantApp = ((IDataSource)this)
                                                     .GetEntities(context)
                                                     .Select(e => e.EntityId);
            IEnumerable <Guid> missingEntities = entitiesInPrevVersion.Except(entitiesInTenantApp).ToList();

            // Step 3: Check database to see if the entities are still present
            ISet <Guid> doNotRemove = new HashSet <Guid>( );
            DataTable   dt          = TableValuedParameter.Create(TableValuedParameterType.Guid);

            foreach (var guid in missingEntities)
            {
                dt.Rows.Add(guid);
            }
            using (IDbCommand command = CreateCommand( ))
            {
                command.CommandText = "dbo.spGetEntityIdsByUpgradeIds";
                command.CommandType = CommandType.StoredProcedure;
                command.AddParameter("@tenantId", DbType.Int64, TenantId);
                command.AddTableValuedParameter("@data", dt);

                using (IDataReader reader = command.ExecuteReader( ))
                {
                    while (reader.Read( ))
                    {
                        var guid = reader.GetGuid(0);
                        doNotRemove.Add(guid);   // entities still in the tenant should be marked as 'do not remove'
                    }
                }
            }

            // Step 4: Include entities marked as 'do not remove' in previous tenants
            var carriedOver = appLibrarySource.GetDoNotRemove(context);

            foreach (Guid guid in carriedOver)
            {
                doNotRemove.Add(guid);
            }

            // Entities that have been removed from the application, but still present in the tenant,
            // should get marked as 'do not delete' to indicate that when the application is upgraded it should not delete the entities.
            return(doNotRemove);
        }
Esempio n. 8
0
 /// <summary>
 ///     Gets the deletions.
 /// </summary>
 /// <param name="tableName">Name of the table.</param>
 /// <param name="tvpType">Type of the TVP.</param>
 /// <returns></returns>
 public DataTable GetDeletions(string tableName, TableValuedParameterType tvpType)
 {
     return(Get(tableName, Deletions, name => TableValuedParameter.Create(tvpType)));
 }
Esempio n. 9
0
 private void GetByArgsOnQuery(DatabaseParameters p, PersonArgs args, IDatabaseArgs dbArgs)
 {
     p.ParamWithWildcard(args?.FirstName, DbMapper.Default[Person.Property_FirstName])
     .ParamWithWildcard(args?.LastName, DbMapper.Default[Person.Property_LastName])
     .TableValuedParamWith(args?.Genders, "GenderCodes", () => TableValuedParameter.Create(args.Genders.ToCodeList()));
 }
        /// <summary>
        /// Prepare the SQL to load in relationships of all applicable types, in one direction.
        /// </summary>
        private void ProcessRelationships(Direction relDirection)
        {
            // Creates a list of relationship transition rules, where each tuple contains (in order):
            // 1. the node that the relationship instruction applies to
            // 2. the relationship ID
            // 3. the node that the relationship points to

            var relRequests =
                from nodeInfo in _requestNodeMap.Values
                from relReq in nodeInfo.Request.Relationships
                where Entity.GetDirection(relReq.RelationshipTypeId, relReq.IsReverse) == relDirection
                select new { NodeInfo = nodeInfo, RelRequest = relReq };

            var dt = TableValuedParameter.Create(TableValuedParameterType.BulkRelType);

            //var relMap = new List<Tuple<int, long, int>>( );
            var map = new HashSet <Tuple <int, long, int> >( );

            foreach (var relReqInfo in relRequests)
            {
                if (relReqInfo.RelRequest.MetadataOnly)
                {
                    continue; // Don't load actual data
                }
                int nodeId  = relReqInfo.NodeInfo.Tag;
                var relReq  = relReqInfo.RelRequest;
                var mapRule = new Tuple <int, long, int>(nodeId, relReq.RelationshipTypeId.Id,
                                                         _requestNodeMap [relReq.RequestedMembers].Tag);

                if (!map.Contains(mapRule))
                {
                    map.Add(mapRule);

                    dt.Rows.Add(mapRule.Item1, mapRule.Item2, mapRule.Item3);
                }

                if (relReq.IsRecursive)
                {
                    var recursiveRule = new Tuple <int, long, int>(nodeId, relReq.RelationshipTypeId.Id, nodeId);

                    if (!map.Contains(recursiveRule))
                    {
                        map.Add(recursiveRule);

                        dt.Rows.Add(recursiveRule.Item1, recursiveRule.Item2, recursiveRule.Item3);
                    }
                }
            }

            if (map.Count == 0)
            {
                return;
            }

            string tblName = relDirection == Direction.Forward ? "@relFwd" : "@relRev";

            _result.TableValuedParameters [tblName] = dt;

            // Gather metadata for relationship requests
            var relReqs = from node in _request.WalkNodes( )
                          from relReq in node.Relationships
                          select relReq;

            foreach (var relReq in relReqs)
            {
                var relTypeId = relReq.RelationshipTypeId.Id;
                var relEntity = Entity.Get <Relationship>(relTypeId);
                if (relEntity == null)
                {
                    continue;
                }

                long key       = relTypeId;
                var  direction = Entity.GetDirection(relReq.RelationshipTypeId, relReq.IsReverse);
                if (direction == Direction.Reverse)
                {
                    key = -key;
                }

                _result.Relationships [key] = new RelationshipInfo
                {
                    CloneAction        = relEntity.CloneAction_Enum ?? CloneActionEnum_Enumeration.Drop,
                    ReverseCloneAction = relEntity.ReverseCloneAction_Enum ?? CloneActionEnum_Enumeration.Drop,
                    IsLookup           = relEntity.IsLookup(direction),
                    ImpliesSecurity    = (direction == Direction.Forward ? relEntity.SecuresTo : relEntity.SecuresFrom) ?? false ||
                                         (relReq.RelationshipTypeId.Alias == "isOfType" && relReq.RelationshipTypeId.Namespace == "core" && !relReq.IsReverse) // Allow types to be loaded implicitly, without granting write to the type.
                };
            }
        }