Ejemplo n.º 1
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Person>("Id");

            var fields = context.GetSelectedFields();

            foreach (var kvp in fields)
            {
                switch (kvp.Key)
                {
                case "firstName": query.Select($"{alias}.FirstName"); break;

                case "lastName": query.Select($"{alias}.LastName"); break;

                case "emails":
                {
                    var emailAlias = $"{alias}Email";
                    query.LeftJoin($"Email {emailAlias} ON {alias}.Id = {emailAlias}.PersonId");
                    query = emailQueryBuilder.Build(query, kvp.Value, emailAlias);
                }
                break;

                case "phones":
                {
                    var phoneAlias = $"{alias}Phone";
                    query.LeftJoin($"Phone {phoneAlias} ON {alias}.Id = {phoneAlias}.PersonId");
                    query = phoneQueryBuilder.Build(query, kvp.Value, phoneAlias);
                }
                break;
                }
            }

            return(query);
        }
Ejemplo n.º 2
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Person>("Id");

            foreach (var field in context.GetSelectedFields())
            {
                switch (field.Key.ToLower())
                {
                case "firstname":
                    query.Select($"{alias}.FirstName");
                    break;

                case "lastname":
                    query.Select($"{alias}.LastName");
                    break;

                case "address":
                    var addressAlias = $"{alias}Address";
                    query.InnerJoin($"Addresses {addressAlias} on {alias}.AddressId = {addressAlias}.Id");
                    query = new AddressQuery().Build(query, field.Value, addressAlias);
                    break;
                }
            }

            return(query);
        }
Ejemplo n.º 3
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Form_Id");
            query.SplitOn <Form>("Form_Id");

            var fields = context.GetSelectedFields();

            foreach (var kvp in fields)
            {
                switch (kvp.Key)
                {
                case "identification": query.Select($"{alias}.Identification"); break;

                case "formCreationDate": query.Select($"{alias}.FormCreationDate"); break;

                case "formCreationHour": query.Select($"{alias}.FormCreationHour"); break;

                case "attestationStatus": query.Select($"{alias}.AttestationStatus"); break;

                case "typeForm": query.Select($"{alias}.TypeForm"); break;

                case "employerDeclarations":
                {
                    var employerDeclarationAlias = $"{alias}EmployerDeclaration";
                    query.LeftJoin($"EmployerDeclaration {employerDeclarationAlias} ON {alias}.Form_Id = {employerDeclarationAlias}.Form_Id");
                    query = _employerDeclarationBuilder.Build(query, kvp.Value, employerDeclarationAlias);
                }
                break;
                }
            }

            return(query);
        }
Ejemplo n.º 4
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <City>("Id");

            foreach (var field in context.GetSelectedFields())
            {
                switch (field.Key.ToLower())
                {
                case "name":
                    query.Select($"{alias}.Name");
                    break;

                case "zipcode":
                    query.Select($"{alias}.ZipCode");
                    break;

                case "country":
                    var countryAlias = $"{alias}Country";
                    query.InnerJoin($"Countries {countryAlias} on {alias}.CountryId = {countryAlias}.Id");
                    query = new CountryQuery().Build(query, field.Value, countryAlias);
                    break;
                }
            }

            return(query);
        }
Ejemplo n.º 5
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Company>("Id");

            var fields = context.GetSelectedFields();

            if (fields.ContainsKey("name"))
            {
                query.Select($"{alias}.Name");
            }
            if (fields.ContainsKey("emails"))
            {
                var companyEmailAlias = $"{alias}CompanyEmail";
                var emailAlias        = $"{alias}Email";
                query
                .LeftJoin($"CompanyEmail {companyEmailAlias} ON {alias}.Id = {companyEmailAlias}.PersonId")
                .LeftJoin($"Email {emailAlias} ON {companyEmailAlias}.EmailId = {emailAlias}.Id");
                query = emailQueryBuilder.Build(query, fields["emails"], emailAlias);
            }
            if (fields.ContainsKey("phones"))
            {
                var companyPhoneAlias = $"{alias}CompanyPhone";
                var phoneAlias        = $"{alias}Phone";
                query
                .LeftJoin($"CompanyPhone {companyPhoneAlias} ON {alias}.Id = {companyPhoneAlias}.PersonId")
                .LeftJoin($"Phone {phoneAlias} ON {companyPhoneAlias}.PhoneId = {phoneAlias}.Id");
                query = phoneQueryBuilder.Build(query, fields["phones"], phoneAlias);
            }

            return(query);
        }
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Person>("Id");

            var fields = context.GetSelectedFields();

            if (fields.ContainsKey("firstName"))
            {
                query.Select($"{alias}.FirstName");
            }
            if (fields.ContainsKey("lastName"))
            {
                query.Select($"{alias}.LastName");
            }
            if (fields.ContainsKey("companies"))
            {
                var personCompanies = $"{alias}PersonCompany";
                var companyAlias    = $"{alias}Company";
                query
                .LeftJoin($"PersonCompany {personCompanies} ON {alias}.Id = {personCompanies}.PersonId")
                .LeftJoin($"Company {companyAlias} ON {personCompanies}.CompanyId = {companyAlias}.Id");
                query = emailQueryBuilder.Build(query, fields["companies"], companyAlias);
            }
            if (fields.ContainsKey("emails"))
            {
                var personEmailAlias = $"{alias}PersonEmail";
                var emailAlias       = $"{alias}Email";
                query
                .LeftJoin($"PersonEmail {personEmailAlias} ON {alias}.Id = {personEmailAlias}.PersonId")
                .LeftJoin($"Email {emailAlias} ON {personEmailAlias}.EmailId = {emailAlias}.Id");
                query = emailQueryBuilder.Build(query, fields["emails"], emailAlias);
            }
            if (fields.ContainsKey("phones"))
            {
                var personPhoneAlias = $"{alias}PersonPhone";
                var phoneAlias       = $"{alias}Phone";
                query
                .LeftJoin($"PersonPhone {personPhoneAlias} ON {alias}.Id = {personPhoneAlias}.PersonId")
                .LeftJoin($"Phone {phoneAlias} ON {personPhoneAlias}.PhoneId = {phoneAlias}.Id");
                query = phoneQueryBuilder.Build(query, fields["phones"], phoneAlias);
            }
            if (fields.ContainsKey("supervisor"))
            {
                var supervisorAlias = $"{alias}Supervisor";
                query.LeftJoin($"Person {supervisorAlias} ON {alias}.SupervisorId = {supervisorAlias}.Id");
                query = Build(query, fields["supervisor"], supervisorAlias);
            }
            if (fields.ContainsKey("careerCounselor"))
            {
                var careerCounselorAlias = $"{alias}CareerCounselor";
                query.LeftJoin($"Person {careerCounselorAlias} ON {alias}.CareerCounselorId = {careerCounselorAlias}.Id");
                query = Build(query, fields["careerCounselor"], careerCounselorAlias);
            }

            return(query);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Returns the inline fragment for the specified entity within the GraphQL selection.
 /// </summary>
 /// <typeparam name="TEntityType">The type of entity to retrieve.</typeparam>
 /// <param name="selectionSet">The GraphQL selection set.</param>
 /// <returns>The inline framgent associated with the entity.</returns>
 public static InlineFragment GetInlineFragment <TEntityType>(this IHaveSelectionSet selectionSet)
 {
     return(selectionSet
            .SelectionSet?
            .Selections?
            .OfType <InlineFragment>()
            .Where(f => f.Type?.Name == typeof(TEntityType).Name)
            .FirstOrDefault());
 }
        /// <summary>
        /// Returns a map of selected fields, keyed by the field name.
        /// </summary>
        /// <param name="haveSelectionSet">The GraphQL selection set container.</param>
        /// <returns>A dictionary whose key is the field name, and value is the field contents.</returns>
        public static IDictionary <string, Field> GetSelectedFields(this IHaveSelectionSet haveSelectionSet)
        {
            var fields = haveSelectionSet
                         .SelectionSet
                         .Selections
                         .OfType <Field>()
                         .ToDictionary(field => field.Name);

            return(fields);
        }
Ejemplo n.º 9
0
 public Task <IEnumerable <object> > GetAsync(
     IHaveSelectionSet context,
     EntityMetadataContext metadata)
 {
     return(Task.FromResult(Enumerable.Range(1, 10).Select(e =>
     {
         var instance = Activator.CreateInstance(metadata.Type);
         return instance;
     })));
 }
        /// <summary>
        /// For a node with a selection set, returns a list of variable references along with what input type each were referenced for.
        /// </summary>
        public List <VariableUsage> GetVariables(IHaveSelectionSet node)
        {
            var usages = new List <VariableUsage>();
            var info   = new TypeInfo(Schema);

            var listener = new MatchingNodeVisitor <VariableReference, (List <VariableUsage> usages, TypeInfo info)>((usages, info), (varRef, __, state) => state.usages.Add(new VariableUsage(varRef, state.info.GetInputType())));

            new BasicVisitor(info, listener).Visit(node, this);

            return(usages);
        }
Ejemplo n.º 11
0
        private static string[] GetSelectedFields(this IHaveSelectionSet field)
        {
            var fields = field
                         .SelectionSet
                         .Selections
                         .OfType <Field>()
                         .Where(p => !p.SelectionSet.Selections.Any())
                         .Select(p => p.Name.ToPascalCase()).ToArray();

            return(fields);
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Returns a map of selected fields, keyed by the field name.
 /// </summary>
 /// <param name="selectionSet">The GraphQL selection set container.</param>
 /// <returns>A dictionary whose key is the field name, and value is the field contents.</returns>
 public static IDictionary <string, Field> GetSelectedFields(this IHaveSelectionSet selectionSet)
 {
     if (selectionSet != null)
     {
         var fields = selectionSet
                      .SelectionSet
                      .Selections
                      .OfType <Field>()
                      .ToDictionary(field => field.Name, StringComparer.OrdinalIgnoreCase);
         return(fields);
     }
     return(null);
 }
Ejemplo n.º 13
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Person>("Id");

            var fields = context.GetSelectedFields();

            foreach (var kvp in fields)
            {
                switch (kvp.Key)
                {
                case "firstName": query.Select($"{alias}.FirstName"); break;

                case "lastName": query.Select($"{alias}.LastName"); break;

                case "emails":
                {
                    var emailAlias = $"{alias}Email";
                    query.LeftJoin($"Email {emailAlias} ON {alias}.Id = {emailAlias}.PersonId");
                    query = emailQueryBuilder.Build(query, kvp.Value, emailAlias);
                }
                break;

                case "phones":
                {
                    var phoneAlias = $"{alias}Phone";
                    query.LeftJoin($"Phone {phoneAlias} ON {alias}.Id = {phoneAlias}.PersonId");
                    query = phoneQueryBuilder.Build(query, kvp.Value, phoneAlias);
                }
                break;
                }
            }

            if (fields.ContainsKey("supervisor"))
            {
                var supervisorAlias = $"{alias}Supervisor";
                query.LeftJoin($"Person {supervisorAlias} ON {alias}.SupervisorId = {supervisorAlias}.Id");
                query = Build(query, fields["supervisor"], supervisorAlias);
            }
            if (fields.ContainsKey("careerCounselor"))
            {
                var careerCounselorAlias = $"{alias}CareerCounselor";
                query.LeftJoin($"Person {careerCounselorAlias} ON {alias}.CareerCounselorId = {careerCounselorAlias}.Id");
                query = Build(query, fields["careerCounselor"], careerCounselorAlias);
            }

            return(query);
        }
Ejemplo n.º 14
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            // Always get the ID of the email
            query.Select($"{alias}.Id");
            // Tell Dapper where the Email class begins (at the Id we just selected)
            query.SplitOn <Email>("Id");

            var fields = context.GetSelectedFields();

            if (fields.ContainsKey("address"))
            {
                query.Select($"{alias}.Address");
            }

            return(query);
        }
Ejemplo n.º 15
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Email>("Id");

            var fields = context.GetSelectedFields();

            foreach (var kvp in fields)
            {
                switch (kvp.Key)
                {
                case "address": query.Select($"{alias}.Address"); break;
                }
            }

            return(query);
        }
Ejemplo n.º 16
0
        public List <VariableUsage> GetVariables(IHaveSelectionSet node)
        {
            var usages = new List <VariableUsage>();
            var info   = new TypeInfo(Schema);

            var listener = new EnterLeaveListener(_ =>
            {
                _.Match <VariableReference>(
                    varRef => usages.Add(new VariableUsage(varRef, info.GetInputType()))
                    );
            });

            var visitor = new BasicVisitor(info, listener);

            visitor.Visit(node);

            return(usages);
        }
        /// <summary>
        /// Builds an entity mapper for the given entity type.
        /// </summary>
        /// <typeparam name="TEntityType">The type of entity to be mapped.</typeparam>
        /// <param name="resolve">A function that, given one or more entities, resolves to an entity instance to which child entities will be added.</param>
        /// <param name="selectionSet">The GraphQL selection set (optional).</param>
        /// <param name="splitOn">The types the query is split on.</param>
        /// <param name="shouldFilterDuplicates">True if duplicate objects should be filtered, false otherwise.</param>
        /// <returns>A Dapper mapping function.</returns>
        public Func <object[], TEntityType> Build <TEntityType>(
            Func <TEntityType, TEntityType, TEntityType> resolve = null,
            IHaveSelectionSet selectionSet = null,
            List <Type> splitOn            = null,
            bool shouldFilterDuplicates    = true)
            where TEntityType : class
        {
            if (resolve == null)
            {
                // A non-resolver, always resolves to the next object provided.
                resolve = (previous, current) => current;
            }

            // Build an entity mapper for the given type
            var mapper = serviceProvider.GetService(typeof(IEntityMapper <TEntityType>)) as IEntityMapper <TEntityType>;

            if (mapper == null)
            {
                throw new InvalidOperationException($"Could not find a mapper for type {typeof(IEntityMapper<TEntityType>).Name}");
            }

            TEntityType entity = null;

            // Setup the mapper to properly resolve its entity
            mapper.ResolveEntity = e => resolve(entity, e);

            return(objs =>
            {
                // Map the object
                var next = mapper.Map(objs, selectionSet, splitOn);

                // Return null if we are returning a duplicate object
                if (shouldFilterDuplicates && object.ReferenceEquals(next, entity))
                {
                    return null;
                }

                // Save a reference to the entity
                entity = next;

                // And, return it
                return entity;
            });
        }
Ejemplo n.º 18
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Phone>("Id");

            var fields = context.GetSelectedFields();

            foreach (var kvp in fields)
            {
                switch (kvp.Key)
                {
                case "number": query.Select($"{alias}.Number"); break;

                case "type": query.Select($"{alias}.Type"); break;
                }
            }

            return(query);
        }
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.EmployerDeclaration_Id");
            query.SplitOn <EmployerDeclaration>("EmployerDeclaration_Id");

            var fields = context.GetSelectedFields();

            foreach (var kvp in fields)
            {
                switch (kvp.Key)
                {
                case "quarter": query.Select($"{alias}.Quarter"); break;

                case "CompanyID": query.Select($"{alias}.CompanyID"); break;

                case "EmployerDeclaration_Id": query.Select($"{alias}.EmployerDeclaration_Id"); break;
                }
            }
            return(query);
        }
Ejemplo n.º 20
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Country>("Id");

            foreach (var field in context.GetSelectedFields())
            {
                switch (field.Key.ToLower())
                {
                case "name":
                    query.Select($"{alias}.Name");
                    break;

                case "isocode":
                    query.Select($"{alias}.IsoCode");
                    break;
                }
            }

            return(query);
        }
        /// <summary>
        /// Builds an entity mapper for the given entity type.
        /// </summary>
        /// <typeparam name="TEntityType">The type of entity to be mapped.</typeparam>
        /// <param name="resolve">A function that compares two values on the entity for equality, usually comparing primary keys.</param>
        /// <param name="selectionSet">The GraphQL selection set (optional).</param>
        /// <param name="splitOn">The types the query is split on.</param>
        /// <returns>A Dapper mapping function.</returns>
        public Func <object[], TEntityType> Build <TEntityType>(
            Func <TEntityType, object> selector,
            IHaveSelectionSet selectionSet = null,
            List <Type> splitOn            = null)
            where TEntityType : class
        {
            var resolve = new Func <TEntityType, TEntityType, TEntityType>(
                (previous, current) =>
            {
                TEntityType result = current;
                if (previous != null)
                {
                    // Compare against values on the objects (usually a primary key)
                    result = object.Equals(selector(previous), selector(current)) ? previous : current;
                }
                return(result);
            }
                );

            // Build the mapper
            return(Build(resolve, selectionSet, splitOn));
        }
Ejemplo n.º 22
0
        public override Form Map(object[] objs, IHaveSelectionSet selectionSet = null, List <Type> splitOn = null)
        {
            Form employee = null;

            foreach (var obj in objs)
            {
                if (employee == null &&
                    obj is Form p)
                {
                    employee = ResolveEntity(p);
                    continue;
                }

                if (obj is EmployerDeclaration employerDeclaration && employee.EmployerDeclarations != null)
                {
                    var employerDeclarationMapper = _entityMapperFactory.Build <EmployerDeclaration>(
                        employerDeclarations => (employerDeclarations.EmployerDeclaration_Id),
                        selectionSet,
                        splitOn
                        );
                    var result = employerDeclarationMapper(objs);
                    if (!employee.EmployerDeclarations.Any(declaration => declaration.EmployerDeclaration_Id == employerDeclaration.EmployerDeclaration_Id))
                    {
                        employee.EmployerDeclarations.Add(result);
                    }
                    else
                    {
                        var declaration = employee.EmployerDeclarations.FirstOrDefault(x =>
                                                                                       x.EmployerDeclaration_Id == result.EmployerDeclaration_Id);
                        if (declaration != null)
                        {
                            ((List <NaturalPerson>)declaration.NaturalPersons).AddRange(result.NaturalPersons);
                        }
                    }
                }
            }
            return(employee);
        }
Ejemplo n.º 23
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            query.Select($"{alias}.Id");
            query.SplitOn <Address>("Id");

            foreach (var field in context.GetSelectedFields())
            {
                switch (field.Key.ToLower())
                {
                case "street":
                    query.Select($"{alias}.Street");
                    break;

                case "city":
                    var cityAlias = $"{alias}City";
                    query.InnerJoin($"Cities {cityAlias} on {alias}.CityId = {cityAlias}.Id");
                    query = new CityQuery().Build(query, field.Value, cityAlias);
                    break;
                }
            }

            return(query);
        }
Ejemplo n.º 24
0
        public override EmployerDeclaration Map(object[] objs, IHaveSelectionSet selectionSet = null, List <Type> splitOn = null)
        {
            EmployerDeclaration declaration = null;

            foreach (var obj in objs)
            {
                if (declaration == null &&
                    obj is EmployerDeclaration p)
                {
                    declaration = ResolveEntity(p);
                }

                //if (obj is NaturalPerson naturalPerson && declaration != null && declaration.NaturalPersons != null)
                //{
                //    var naturalPersonMapper = _entityMapperFactory.Build<NaturalPerson>(
                //        naaturalPerson => (naaturalPerson.NaturalPerson_Id),
                //        selectionSet,
                //        splitOn
                //    );

                //    var result = naturalPersonMapper(objs);
                //    if (!declaration.NaturalPersons.Any(_ => _.NaturalPerson_Id == naturalPerson.NaturalPerson_Id))
                //        declaration.NaturalPersons.Add(result);
                //    else
                //    {
                //        //var person = declaration.NaturalPersons.FirstOrDefault(x =>
                //        //    x.NaturalPerson_Id == result.NaturalPerson_Id);
                //        //if (person != null)
                //        //{
                //        //    ((List<WorkerRecord>)person.WorkerRecords).AddRange(result.WorkerRecords);
                //        //}
                //    }
                //}
            }
            return(declaration);
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Maps a row of data to an entity.
 /// </summary>
 /// <param name="objs">A row objects to be mapped.</param>
 /// <param name="selectionSet">The GraphQL selection set (optional).</param>
 /// <param name="splitOn">The types the query is split on.</param>
 /// <returns>The mapped entity, or null if the entity has previously been returned.</returns>
 public abstract TEntityType Map(
     object[] objs,
     IHaveSelectionSet selectionSet = null,
     List <Type> splitOn            = null);
        public override Person Map(
            object[] objs,
            IHaveSelectionSet selectionSet = null,
            List <Type> splitOn            = null)
        {
            Person person = null;

            foreach (var obj in objs)
            {
                if (person == null &&
                    obj is Person p)
                {
                    person = ResolveEntity(p);
                    continue;
                }
                if (obj is Email email &&
                    // Eliminate duplicates
                    !person.Emails.Any(e => e.Address == email.Address))
                {
                    person.Emails.Add(email);
                    continue;
                }
                if (obj is Phone phone &&
                    // Eliminate duplicates
                    !person.Phones.Any(ph => ph.Number == phone.Number))
                {
                    person.Phones.Add(phone);
                    continue;
                }
            }

            if (selectionSet != null)
            {
                var fields          = selectionSet.GetSelectedFields();
                int supervisorIndex = -1;
                // Start at 1 to skip the "first" person object in the list,
                // which is the person we just mapped.
                int startingIndex = 1;

                // NOTE: order matters here, if both supervisor
                // and careerCounselor exist, then supervisor must appear
                // first in the list.  This order is guaranteed in PersonQueryBuilder.
                if (fields.ContainsKey("supervisor"))
                {
                    supervisorIndex = splitOn.IndexOf(typeof(Person), startingIndex);
                    if (supervisorIndex >= 0)
                    {
                        person.Supervisor = objs[supervisorIndex] as Person;
                    }
                }
                if (fields.ContainsKey("careerCounselor"))
                {
                    var careerCounselorIndex = splitOn.IndexOf(typeof(Person), Math.Max(startingIndex, supervisorIndex + 1));
                    if (careerCounselorIndex >= 0)
                    {
                        person.CareerCounselor = objs[careerCounselorIndex] as Person;
                    }
                }
            }

            return(person);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Maps the next object from Dapper.
        /// </summary>
        /// <typeparam name="TItemType">The item type to be mapped.</typeparam>
        /// <param name="context">The context used to map object from Dapper.</param>
        /// <param name="fieldNames">The names of one or more GraphQL fields associated with the item.</param>
        /// <param name="entityMapper">An optional entity mapper.  This is used to map complex objects from Dapper mapping results.</param>
        /// <returns>The mapped item.</returns>
        public TItemType Next <TItemType>(
            IEnumerable <string> fieldNames,
            Func <IDictionary <string, Field>, IHaveSelectionSet, IHaveSelectionSet> getSelectionSet,
            IEntityMapper <TItemType> entityMapper = null)
            where TItemType : class
        {
            if (fieldNames == null)
            {
                throw new ArgumentNullException(nameof(fieldNames));
            }

            if (ItemEnumerator == null ||
                SplitOnEnumerator == null)
            {
                throw new NotSupportedException("Cannot call Next() before calling Start()");
            }

            lock (LockObject)
            {
                var keys = fieldNames.Intersect(CurrentSelectionSet.Keys);
                if (keys.Any())
                {
                    TItemType item = default(TItemType);
                    while (
                        ItemEnumerator.MoveNext() &&
                        SplitOnEnumerator.MoveNext())
                    {
                        // Whether a non-null object exists at this position or not,
                        // the SplitOn is expecting this type here, so we will yield it.
                        if (SplitOnEnumerator.Current == typeof(TItemType))
                        {
                            item = ItemEnumerator.Current as TItemType;
                            break;
                        }
                    }

                    if (entityMapper != null)
                    {
                        // Determine where the next entity mapper will get its selection set from
                        IHaveSelectionSet selectionSet = getSelectionSet(CurrentSelectionSet, SelectionSet);

                        var nextContext = new EntityMapContext
                        {
                            Items        = Items.Skip(MappedCount),
                            SelectionSet = selectionSet,
                            SplitOn      = SplitOn.Skip(MappedCount),
                        };
                        using (nextContext)
                        {
                            item = entityMapper.Map(nextContext);

                            // Update enumerators to skip past items already mapped
                            var mappedCount = nextContext.MappedCount;
                            MappedCount += nextContext.MappedCount;
                            int i = 0;
                            while (
                                // Less 1, the next time we iterate we
                                // will advance by 1 as part of the iteration.
                                i < mappedCount - 1 &&
                                ItemEnumerator.MoveNext() &&
                                SplitOnEnumerator.MoveNext())
                            {
                                i++;
                            }
                        }
                    }
                    else
                    {
                        MappedCount++;
                    }
                    return(item);
                }
            }
            return(default(TItemType));
        }
Ejemplo n.º 28
0
        public IEnumerable<VariableUsage> GetVariables(IHaveSelectionSet node)
        {
            var usages = new List<VariableUsage>();
            var info = new TypeInfo(Schema);

            var listener = new EnterLeaveListener(_ =>
            {
                _.Match<VariableReference>(
                    varRef => usages.Add(new VariableUsage {Node = varRef, Type = info.GetInputType()})
                );
            });

            var visitor = new BasicVisitor(info, listener);
            visitor.Visit(node);

            return usages;
        }
Ejemplo n.º 29
0
        private static SqlGenerationContext GenerateSQL(
            IHaveSelectionSet context,
            EntityMetadataContext metadata,
            SqlGenerationContext sqlContext = null,
            SQLOperation operation          = SQLOperation.SELECT,
            int level          = 0,
            string parentAlias = null,
            EntityMetadataRelation relationMetadata = null)
        {
            if (sqlContext == null)
            {
                sqlContext = new SqlGenerationContext();
            }

            var key = metadata.Keys.Values.ToArray();

            var schema =
                metadata.CustomMetadata.TryGetValue(Globals.CUSTOM_METADATA_SCHEMA, out var customSchema) ?
                customSchema : "dbo";

            var table =
                metadata.CustomMetadata.TryGetValue(Globals.CUSTOM_METADATA_TABLE, out var customTable) ?
                customTable : metadata.Type.Name;

            var queriedFields = context.GetSelectedFields();

            var alias = GetAlias(level);

            var entityFields =
                metadata.Included.Keys
                .Select(f => f.ToLower())
                .Intersect(queriedFields.Keys)
                .Select(f => new { field = $"{f}", exp = $"{alias}.[{f}]" })
                .ToArray();

            sqlContext.SelectFields.AddRange(entityFields);
            sqlContext.SplitOnTypes.Add(metadata.Type);
            if (level > 0)
            {
                sqlContext.SplitOnFields.Add(entityFields.First().field);
            }

            if (operation == SQLOperation.SELECT)
            {
                sqlContext.Sql = $"SELECT %fields% FROM [{schema}].[{table}] {alias}";

                foreach (var field in queriedFields)
                {
                    if (metadata.Relations.TryGetValue(field.Key.ToLower(), out var relation))
                    {
                        sqlContext.Relations.Add(relation);
                        GenerateSQL(
                            field.Value,
                            relation.EntityRight,
                            sqlContext,
                            operation: SQLOperation.JOIN,
                            level: level + 1,
                            parentAlias: alias,
                            relationMetadata: relation
                            );
                    }
                }
            }
            else if (operation == SQLOperation.JOIN)
            {
                if (relationMetadata.IsCollection)
                {
                    sqlContext.Sql += $" LEFT JOIN [{schema}].[{table}] {alias} ON {ManyForeignKeyCriteria(parentAlias, alias, relationMetadata)}";
                }
                else
                {
                    sqlContext.Sql += $" LEFT JOIN [{schema}].[{table}] {alias} ON {SingleForeignKeyCriteria(parentAlias, alias, relationMetadata)}";
                }
            }

            if (level == 0)
            {
                sqlContext.Sql = sqlContext.Sql.Replace("%fields%", string.Join(",", sqlContext.SelectFields.Select(x => x.exp)));
            }

            return(sqlContext);
        }
Ejemplo n.º 30
0
        public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias)
        {
            var mergedAlias = $"{alias}Merged";

            // Deduplicate the person
            query.LeftJoin($"Person {mergedAlias} ON {alias}.MergedToPersonId = {mergedAlias}.MergedToPersonId");
            query.Select($"{alias}.Id", $"{alias}.MergedToPersonId");
            query.SplitOn <Person>("Id");

            var fields = QueryBuilderHelper.CollectFields(context.SelectionSet);

            if (QueryBuilderHelper.IsConnection(context.SelectionSet))
            {
                query.Select($"{alias}.CreateDate");
            }

            if (fields.ContainsKey("firstName"))
            {
                query.Select($"{mergedAlias}.FirstName");
            }
            if (fields.ContainsKey("lastName"))
            {
                query.Select($"{mergedAlias}.LastName");
            }
            if (fields.ContainsKey("companies"))
            {
                var personCompanyAlias = $"{alias}PersonCompany";
                var companyAlias       = $"{alias}Company";
                query
                .LeftJoin($"PersonCompany {personCompanyAlias} ON {mergedAlias}.Id = {personCompanyAlias}.PersonId")
                .LeftJoin($"Company {companyAlias} ON {personCompanyAlias}.CompanyId = {companyAlias}.Id");
                query = companyQueryBuilder.Build(query, fields["companies"], companyAlias);
            }
            if (fields.ContainsKey("emails"))
            {
                var personEmailAlias = $"{alias}PersonEmail";
                var emailAlias       = $"{alias}Email";
                query
                .LeftJoin($"PersonEmail {personEmailAlias} ON {mergedAlias}.Id = {personEmailAlias}.PersonId")
                .LeftJoin($"Email {emailAlias} ON {personEmailAlias}.EmailId = {emailAlias}.Id");
                query = emailQueryBuilder.Build(query, fields["emails"], emailAlias);
            }
            if (fields.ContainsKey("phones"))
            {
                var personPhoneAlias = $"{alias}PersonPhone";
                var phoneAlias       = $"{alias}Phone";
                query
                .LeftJoin($"PersonPhone {personPhoneAlias} ON {mergedAlias}.Id = {personPhoneAlias}.PersonId")
                .LeftJoin($"Phone {phoneAlias} ON {personPhoneAlias}.PhoneId = {phoneAlias}.Id");
                query = phoneQueryBuilder.Build(query, fields["phones"], phoneAlias);
            }
            if (fields.ContainsKey("supervisor"))
            {
                var supervisorAlias = $"{alias}Supervisor";
                query.LeftJoin($"Person {supervisorAlias} ON {mergedAlias}.SupervisorId = {supervisorAlias}.Id");
                query = Build(query, fields["supervisor"], supervisorAlias);
            }
            if (fields.ContainsKey("careerCounselor"))
            {
                var careerCounselorAlias = $"{alias}CareerCounselor";
                query.LeftJoin($"Person {careerCounselorAlias} ON {mergedAlias}.CareerCounselorId = {careerCounselorAlias}.Id");
                query = Build(query, fields["careerCounselor"], careerCounselorAlias);
            }

            return(query);
        }
Ejemplo n.º 31
0
        public async Task <IEnumerable <dynamic> > GetAsync(
            IHaveSelectionSet context,
            EntityMetadataContext metadata)
        {
            using (var connection = connectionFactory())
            {
                var sql = GenerateSQL(context, metadata);

                HashSet <object>[] mapping =
                    Enumerable.Range(1, sql.SplitOnTypes.Count())
                    .Select(x => new HashSet <object>())
                    .ToArray();

                List <dynamic>[] objectCache =
                    Enumerable.Range(1, sql.SplitOnTypes.Count())
                    .Select(x => new List <dynamic>())
                    .ToArray();

                object[] lastEntities = new dynamic[sql.SplitOnTypes.Count()];

                (await connection.QueryAsync <dynamic>(
                     sql.Sql,
                     sql.SplitOnTypes.ToArray(),
                     splitOn: string.Join(",", sql.SplitOnFields),
                     map: (entities) =>
                {
                    object result = entities[0];

                    int i = 0;
                    foreach (var entity in entities)
                    {
                        var entityKey =
                            i == 0 ?
                            metadata.PrimaryKey(entity) :
                            sql.Relations[i - 1].EntityRight.PrimaryKey(entity);

                        if (mapping[i].Contains(entityKey))
                        {
                            if (i == 0)
                            {
                                result = null;
                            }
                        }
                        else
                        {
                            if (lastEntities[i] != null)
                            {
                                if (i < objectCache.Length - 1)
                                {
                                    foreach (var obj in objectCache[i + 1])
                                    {
                                        if (sql.Relations[i].IsCollection)
                                        {
                                            sql.Relations[i].Add(lastEntities[i], obj);
                                        }
                                        else
                                        {
                                            sql.Relations[i].Set(lastEntities[i], obj);
                                        }
                                    }
                                    objectCache[i + 1].Clear();
                                    mapping[i + 1].Clear();
                                }
                            }

                            objectCache[i].Add(entity);
                            mapping[i].Add(entityKey);
                            lastEntities[i] = entity;
                        }

                        i++;
                    }

                    return(result);
                }
                     )).ToArray();

                int idx = 0;
                foreach (var entity in lastEntities)
                {
                    if (entity != null)
                    {
                        if (idx < objectCache.Length - 1)
                        {
                            foreach (var obj in objectCache[idx + 1])
                            {
                                if (sql.Relations[idx].IsCollection)
                                {
                                    sql.Relations[idx].Add(entity, obj);
                                }
                                else
                                {
                                    sql.Relations[idx].Set(entity, obj);
                                }
                            }
                            objectCache[idx + 1].Clear();
                        }
                    }
                    idx++;
                }

                return(objectCache[0]);
            }
        }