public async Task Create_JsonCommand_CommandPropertiesMatchExpected()
        {
            var providerFactory = new PostgreSqlProviderFactory(new DataAnnotationsDefinitionProvider());

            using (var provider = providerFactory.Create(ConfigurationRoot.GetConnectionString("OrmTestDbPg")))
            {
                var target = new JsonCommandFactory();
                await provider.DatabaseContext.OpenSharedConnectionAsync(CancellationToken.None);

                var actual = target.Create(provider.DatabaseContext, "Select * from 'Mytable'", "MyParameter", new List <DependentRow>());
                Assert.IsInstanceOfType(actual, typeof(NpgsqlCommand));
                Assert.AreEqual("Select * from 'Mytable'", actual.CommandText);
                var actualParameter = actual.Parameters["MyParameter"] as NpgsqlParameter;
                Assert.IsNotNull(actualParameter);
                Assert.AreEqual(NpgsqlDbType.Jsonb, actualParameter.NpgsqlDbType);
            }
        }
Exemplo n.º 2
0
        public void ExecuteForResults_GenericSubmission_DoesNotThrowException()
        {
            var providerFactory = new PostgreSqlProviderFactory(new DataAnnotationsDefinitionProvider());

            using (var provider = providerFactory.Create(ConfigurationRoot.GetConnectionString("OrmTestDbPg")))
            {
                var identityRepository = new EntityRepository <DomainIdentity, DomainIdentityRow>(provider, this.mapper);

                var domainIdentity = identityRepository.FirstOrDefault(
                    Query.Select <DomainIdentity>()
                    .Where(set => set.AreEqual(identity => identity.UniqueIdentifier, Environment.UserName)))
                                     ?? identityRepository.Save(
                    new DomainIdentity(Environment.UserName)
                {
                    FirstName  = "King",
                    MiddleName = "T.",
                    LastName   = "Animal"
                });

                var expected   = new GenericSubmission("My Submission", domainIdentity);
                var internalId = new Field
                {
                    Name        = "Internal ID",
                    Description = "Unique ID used internally"
                };

                var firstName = new Field
                {
                    Name        = "First Name",
                    Description = "The person's first name"
                };

                var lastName = new Field
                {
                    Name        = "Last Name",
                    Description = "The person's last name"
                };

                var yearlyWage = new Field
                {
                    Name        = "Yearly Wage",
                    Description = "The base wage paid year over year."
                };

                var hireDate = new Field
                {
                    Name        = "Hire Date",
                    Description = "The date and time of hire for the person"
                };

                var bonusTarget = new Field
                {
                    Name        = "Bonus Target",
                    Description = "The target bonus for the person"
                };

                var contactNumbers = new Field
                {
                    Name        = "Contact Numbers",
                    Description = "A list of contact numbers for the person in order of preference"
                };

                expected.SetValue(internalId, 9234);
                expected.SetValue(firstName, "Dan");
                expected.SetValue(lastName, "The Man");
                expected.SetValue(yearlyWage, 75100.35m);
                expected.SetValue(hireDate, DateTimeOffset.Now);
                expected.SetValue(bonusTarget, 1.59834578934);
                expected.SetValue(
                    contactNumbers,
                    new List <string>
                {
                    "423-222-2252",
                    "615-982-0012",
                    "+1-555-252-5521"
                });

                expected.Submit();

                var fieldRepository = new EntityRepository <Field, FieldRow>(provider, this.mapper);

                var fields          = expected.SubmissionValues.Select(value => value.Field).Distinct().ToDictionary(field => field.Name, field => field);
                var inclusionValues = fields.Keys.ToArray();
                var existingFields  =
                    fieldRepository.SelectEntities(new EntitySelection <Field>().Where(set => set.Include(field => field.Name, inclusionValues)));

                foreach (var field in existingFields)
                {
                    var output = fields[field.Name];
                    this.mapper.MapTo(field, output);
                }

                foreach (var field in fields.Values.Where(field => field.FieldId.HasValue == false))
                {
                    fieldRepository.Save(field);
                }

                var submissionRepository = new EntityRepository <GenericSubmission, GenericSubmissionRow>(provider, this.mapper);

                var transaction = provider.BeginTransaction();
                submissionRepository.Save(expected);

                var submissionId = expected.GenericSubmissionId.GetValueOrDefault();
                Assert.AreNotEqual(0, submissionId);

                // Set up the structured command provider.
                var structuredCommandProvider = new JsonCommandFactory();

                // Do the field values
                var valuesList = from v in expected.SubmissionValues
                                 select new FieldValueRow
                {
                    FieldId = v.Field.FieldId.GetValueOrDefault(),
                    LastModifiedByDomainIdentifierId = domainIdentity.DomainIdentityId.GetValueOrDefault(),
                    LastModifiedTime = expected.SubmittedTime
                };

                var valuesCommand =
                    new JsonInsert <FieldValueRow>(provider.DatabaseContext)
                    .Returning(row => row.FieldValueId, row => row.FieldId);

                var insertedValues = valuesCommand.ExecuteForResults(valuesList).ToList();

                // Map back to the domain object.
                foreach (var value in expected.SubmissionValues)
                {
                    var input = insertedValues.FirstOrDefault(row => row.FieldId == value.Field.FieldId);
                    this.mapper.MapTo(input, value);
                }

                // Do the field value elements
                var elementsList = (from e in expected.SubmissionValues.SelectMany(value => value.Elements)
                                    select new FieldValueElementPgFlatRow
                {
                    FieldValueElementId = e.FieldValueElementId,
                    FieldValueId = e.FieldValue.FieldValueId.GetValueOrDefault(),
                    Order = e.Order,
                    DateElement = e.Element as DateTimeOffset? ?? e.Element as DateTime?,
                    FloatElement = e.Element as double? ?? e.Element as float?,
                    IntegerElement = e.Element as long? ?? e.Element as int? ?? e.Element as short? ?? e.Element as byte?,
                    MoneyElement = e.Element as decimal?,
                    TextElement = e.Element as string                     // here we actually want it to be null if it is not a string
                }).ToList();

                var elementsCommand = new JsonInsert <FieldValueElementPgFlatRow>(provider.DatabaseContext)
                                      .Returning(row => row.FieldValueId, row => row.Order);

                // Reassign with our added identities
                elementsList = elementsCommand.ExecuteForResults(elementsList).ToList();

                foreach (var element in expected.SubmissionValues.SelectMany(value => value.Elements))
                {
                    var input = elementsList.First(row => row.FieldValueId == element.FieldValue.FieldValueId && row.Order == element.Order);
                    this.mapper.MapTo(input, element);
                }

                var dateElementsCommand = new JsonInsert <DateElementRow>(provider.DatabaseContext)
                                          .InsertInto(row => row.DateElementId, row => row.Value)
                                          .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.DateElement);

                dateElementsCommand.Execute(elementsList.Where(row => row.DateElement.HasValue));

                var floatElementsCommand = new JsonInsert <FloatElementRow>(provider.DatabaseContext)
                                           .InsertInto(row => row.FloatElementId, row => row.Value)
                                           .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.FloatElement);

                floatElementsCommand.Execute(elementsList.Where(row => row.FloatElement.HasValue));

                var integerElementsCommand = new JsonInsert <IntegerElementRow>(provider.DatabaseContext)
                                             .InsertInto(row => row.IntegerElementId, row => row.Value)
                                             .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.IntegerElement);

                integerElementsCommand.Execute(elementsList.Where(row => row.IntegerElement.HasValue));

                var moneyElementsCommand = new JsonInsert <MoneyElementRow>(provider.DatabaseContext)
                                           .InsertInto(row => row.MoneyElementId, row => row.Value)
                                           .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.MoneyElement);

                moneyElementsCommand.Execute(elementsList.Where(row => row.MoneyElement.HasValue));

                var textElementsCommand = new JsonInsert <TextElementRow>(provider.DatabaseContext)
                                          .InsertInto(row => row.TextElementId, row => row.Value)
                                          .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.TextElement);

                textElementsCommand.Execute(elementsList.Where(row => row.TextElement != null));

                // Attach the values to the submission
                var genericValueSubmissions = from v in insertedValues
                                              select new GenericSubmissionValueRow
                {
                    GenericSubmissionId      = submissionId,
                    GenericSubmissionValueId = v.FieldValueId
                };

                var submissionCommand = new JsonInsert <GenericSubmissionValueRow>(provider.DatabaseContext);
                submissionCommand.Execute(genericValueSubmissions);
                transaction.Commit();
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Merges the specified <paramref name="submission"/> into the repository backed by the <paramref name="provider"/>.
        /// </summary>
        /// <param name="submission">
        /// The submission.
        /// </param>
        /// <param name="provider">
        /// The provider.
        /// </param>
        private void MergeSubmission(GenericSubmission submission, IRepositoryProvider provider)
        {
            // Merge our existing fields
            var fields     = submission.SubmissionValues.Select(value => value.Field).Distinct().ToList();
            var fieldItems = from f in fields
                             select new FieldRow
            {
                Name        = f.Name,
                Description = f.Description
            };

            // Merge in the field values.
            var commandProvider = new JsonCommandFactory();
            var transaction     = provider.BeginTransaction();

            var fieldsCommand = new JsonInsert <FieldRow>(provider.DatabaseContext).OnConflict(row => row.Name)
                                .Upsert(row => row.Description)
                                .Returning(row => row.FieldId, row => row.Name, row => row.Description);

            var mergedFields = fieldsCommand.ExecuteForResults(fieldItems).ToList();

            foreach (var field in fields)
            {
                var input = mergedFields.FirstOrDefault(f => string.Equals(f.Name, field.Name, StringComparison.Ordinal));

                // Because we are doing a subset, and we know we will get back baseline fields. If MERGE is messed up this will error later when there
                // aren't IDs for baseline fields.
                if (input == null)
                {
                    continue;
                }

                this.mapper.MapTo(input, field);
            }

            var submissionRepository = new EntityRepository <GenericSubmission, GenericSubmissionRow>(provider, this.mapper);

            submissionRepository.Save(submission);

            // Could be mapped as well.
            var fieldValues = from v in submission.SubmissionValues
                              select new FieldValueTableTypeRow
            {
                FieldId = v.Field.FieldId.GetValueOrDefault(),
                LastModifiedByDomainIdentifierId = v.LastModifiedBy.DomainIdentityId.GetValueOrDefault(),
                LastModifiedTime = v.LastModifiedTime
            };

            // We use FieldValueId to essentially ensure we're only affecting the scope of this submission. FieldId on the select brings back
            // only inserted rows matched back to their original fields.
            var fieldValueCommand = new JsonInsert <FieldValueRow>(provider.DatabaseContext);
            var mergedFieldValues = fieldValueCommand.OnConflict(row => row.FieldValueId)
                                    .Upsert(row => row.LastModifiedByDomainIdentifierId, row => row.LastModifiedTime)
                                    .Returning(row => row.FieldValueId, row => row.FieldId, row => row.LastModifiedByDomainIdentifierId, row => row.LastModifiedTime)
                                    .ExecuteForResults(fieldValues)
                                    .ToList();

            Assert.IsTrue(mergedFieldValues.All(row => row.FieldValueId > 0));

            // Map back to the domain object.
            foreach (var value in submission.SubmissionValues)
            {
                var input = mergedFieldValues.First(row => row.FieldId == value.Field.FieldId);
                this.mapper.MapTo(input, value);
                Assert.IsTrue(value.FieldValueId.HasValue);
            }

            // Now merge in the field value elements.
            // Do the field value elements
            var valueElements = (from e in submission.SubmissionValues.SelectMany(value => value.Elements)
                                 select new FieldValueElementPgFlatRow
            {
                FieldValueElementId = e.FieldValueElementId,
                FieldValueId = e.FieldValue.FieldValueId.GetValueOrDefault(),
                Order = e.Order,
                DateElement = e.Element as DateTimeOffset? ?? e.Element as DateTime?,
                FloatElement = e.Element as double? ?? e.Element as float?,
                IntegerElement = e.Element as long? ?? e.Element as int? ?? e.Element as short? ?? e.Element as byte?,
                MoneyElement = e.Element as decimal?,
                TextElement = e.Element as string                      // here we actually want it to be null if it is not a string
            }).ToList();

            var elementMergeCommand = new JsonInsert <FieldValueElementRow>(provider.DatabaseContext);
            var mergedValueElements = elementMergeCommand.OnConflict(row => row.FieldValueElementId)
                                      .Upsert(row => row.Order)
                                      .Returning(row => row.FieldValueElementId, row => row.FieldValueId, row => row.Order)
                                      .ExecuteForResults(valueElements)
                                      .ToList();

            foreach (var element in valueElements)
            {
                var input = mergedValueElements.First(row => row.FieldValueId == element.FieldValueId && row.Order == element.Order);
                this.mapper.MapTo(input, element);
                Assert.IsTrue(element.FieldValueElementId.HasValue);
            }

            var dateElementsCommand = new JsonInsert <DateElementRow>(provider.DatabaseContext)
                                      .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.DateElement)
                                      .OnConflict(row => row.DateElementId)
                                      .Upsert(row => row.Value);

            dateElementsCommand.Execute(valueElements.Where(row => row.DateElement.HasValue));

            var floatElementsCommand = new JsonInsert <FloatElementRow>(provider.DatabaseContext)
                                       .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.FloatElement)
                                       .OnConflict(row => row.FloatElementId)
                                       .Upsert(row => row.Value);

            floatElementsCommand.Execute(valueElements.Where(row => row.FloatElement.HasValue));

            var integerElementsCommand = new JsonInsert <IntegerElementRow>(provider.DatabaseContext)
                                         .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.IntegerElement)
                                         .OnConflict(row => row.IntegerElementId)
                                         .Upsert(row => row.Value);

            integerElementsCommand.Execute(valueElements.Where(row => row.IntegerElement.HasValue));

            var moneyElementsCommand = new JsonInsert <MoneyElementRow>(provider.DatabaseContext)
                                       .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.MoneyElement)
                                       .OnConflict(row => row.MoneyElementId)
                                       .Upsert(row => row.Value);

            moneyElementsCommand.Execute(valueElements.Where(row => row.MoneyElement.HasValue));

            var textElementsCommand = new JsonInsert <TextElementRow>(provider.DatabaseContext)
                                      .From <FieldValueElementPgFlatRow>(row => row.FieldValueElementId, row => row.TextElement)
                                      .OnConflict(row => row.TextElementId)
                                      .Upsert(row => row.Value);

            textElementsCommand.Execute(valueElements.Where(row => row.TextElement != null));

            // Attach the values to the submission
            var genericValueSubmissions = from v in mergedFieldValues
                                          select new GenericSubmissionValueTableTypeRow
            {
                GenericSubmissionId      = submission.GenericSubmissionId.GetValueOrDefault(),
                GenericSubmissionValueId = v.FieldValueId
            };

            var submissionCommand = new JsonInsert <GenericSubmissionValueRow>(provider.DatabaseContext).Upsert(
                row => row.GenericSubmissionValueId,
                row => row.GenericSubmissionId);

            ////.DeleteUnmatchedInSource(row => row.GenericSubmissionId); Can't with PostgreSQL

            submissionCommand.Execute(genericValueSubmissions);
            transaction.Commit();
        }
Exemplo n.º 4
0
        public void ExecuteForResults_ListOfFields_DoesNotThrowException()
        {
            var internalId = new Field
            {
                Name        = "INS_Internal ID",
                Description = "Unique ID used internally"
            };

            var firstName = new Field
            {
                Name        = "INS_First Name",
                Description = "The person's first name"
            };

            var lastName = new Field
            {
                Name        = "INS_Last Name",
                Description = "The person's last name"
            };

            var yearlyWage = new Field
            {
                Name        = "INS_Yearly Wage",
                Description = "The base wage paid year over year."
            };

            var hireDate = new Field
            {
                Name        = "INS_Hire Date",
                Description = "The date and time of hire for the person"
            };

            var bonusTarget = new Field
            {
                Name        = "INS_Bonus Target",
                Description = "The target bonus for the person"
            };

            var contactNumbers = new Field
            {
                Name        = "INS_Contact Numbers",
                Description = "A list of contact numbers for the person in order of preference"
            };

            var fields = new List <Field>
            {
                internalId,
                firstName,
                lastName,
                yearlyWage,
                hireDate,
                bonusTarget,
                contactNumbers
            };

            var providerFactory = new PostgreSqlProviderFactory(new DataAnnotationsDefinitionProvider());

            using (var provider = providerFactory.Create(ConfigurationRoot.GetConnectionString("OrmTestDbPg")))
            {
                var fieldRepository = new EntityRepository <Field, FieldRow>(provider, this.mapper);

                // Delete the existing rows.
                fieldRepository.DeleteSelection(Query.From <FieldRow>().Where(set => set.AreEqual(row => row.Name, "INS_%")));

                var transaction = provider.BeginTransaction();

                // Set up the structured command provider.
                var structuredCommandProvider = new JsonCommandFactory();
                var fieldInsertCommand        =
                    new JsonInsert <FieldRow>(provider.DatabaseContext).Returning(
                        row => row.FieldId,
                        row => row.Description);

                var actual = fieldInsertCommand.ExecuteForResults(
                    fields.Select(
                        field => new FieldRow
                {
                    Name        = field.Name,
                    Description = field.Description
                }));

                foreach (var fieldRow in actual)
                {
                    Assert.AreNotEqual(0, fieldRow.FieldId);
                }

                transaction.Commit();
            }
        }