Example #1
0
        public void ParameterConversion()
        {
            var context = new XrmFakedContext();

            context.InitializeMetadata(Assembly.GetExecutingAssembly());

            var org      = context.GetOrganizationService();
            var metadata = new AttributeMetadataCache(org);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='firstname' operator='eq' value='Mark' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(org, metadata, fetch, new FetchXml2SqlOptions {
                UseParametersForLiterals = true
            }, out var parameters);

            Assert.AreEqual("SELECT firstname, lastname FROM contact WHERE firstname = @firstname", NormalizeWhitespace(converted));
            Assert.AreEqual("Mark", parameters["@firstname"]);
        }
Example #2
0
        public void AndOr()
        {
            var context = new XrmFakedContext();

            context.InitializeMetadata(Assembly.GetExecutingAssembly());

            var org      = context.GetOrganizationService();
            var metadata = new AttributeMetadataCache(org);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='firstname' operator='eq' value='Mark' />
                            <filter type='or'>
                                <condition attribute='lastname' operator='eq' value='Carrington' />
                                <condition attribute='lastname' operator='eq' value='Twain' />
                            </filter>
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(org, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT firstname, lastname FROM contact WHERE firstname = 'Mark' AND (lastname = 'Carrington' OR lastname = 'Twain')", NormalizeWhitespace(converted));
        }
Example #3
0
        public void NextXYearsConversion()
        {
            var context = new XrmFakedContext();

            context.InitializeMetadata(Assembly.GetExecutingAssembly());

            var org      = context.GetOrganizationService();
            var metadata = new AttributeMetadataCache(org);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='createdon' operator='next-x-years' value='2' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(org, metadata, fetch, new FetchXml2SqlOptions {
                PreserveFetchXmlOperatorsAsFunctions = false
            }, out _);

            Assert.AreEqual($"SELECT firstname, lastname FROM contact WHERE createdon >= '{DateTime.Now:s}' AND createdon < '{DateTime.Today.AddDays(1).AddYears(2):s}'", NormalizeWhitespace(converted));
        }
Example #4
0
        public void EqBusinessId()
        {
            var context = new XrmFakedContext();

            context.InitializeMetadata(Assembly.GetExecutingAssembly());
            context.AddFakeMessageExecutor <WhoAmIRequest>(new WhoAmIHandler());

            var org      = context.GetOrganizationService();
            var metadata = new AttributeMetadataCache(org);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='parentcustomerid' operator='eq-businessid' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(org, metadata, fetch, new FetchXml2SqlOptions {
                PreserveFetchXmlOperatorsAsFunctions = false
            }, out _);

            Assert.AreEqual($"SELECT firstname, lastname FROM contact WHERE parentcustomerid = '{WhoAmIHandler.BusinessUnitId:D}'", NormalizeWhitespace(converted));
        }
Example #5
0
        public void JoinFilter()
        {
            var context = new XrmFakedContext();

            context.InitializeMetadata(Assembly.GetExecutingAssembly());

            var org      = context.GetOrganizationService();
            var metadata = new AttributeMetadataCache(org);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <link-entity name='account' from='accountid' to='parentcustomerid'>
                            <attribute name='name' />
                            <filter>
                                <condition attribute='name' operator='eq' value='data8' />
                            </filter>
                        </link-entity>
                        <filter>
                            <condition attribute='firstname' operator='eq' value='Mark' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(org, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT contact.firstname, contact.lastname, account.name FROM contact INNER JOIN account ON contact.parentcustomerid = account.accountid AND account.name = 'data8' WHERE contact.firstname = 'Mark'", NormalizeWhitespace(converted));
        }
Example #6
0
        public void Distinct()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch distinct='true'>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT DISTINCT firstname, lastname FROM contact", NormalizeWhitespace(converted));
        }
Example #7
0
        public void Order()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <order attribute='firstname' />
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT firstname, lastname FROM contact ORDER BY firstname ASC", NormalizeWhitespace(converted));
        }
Example #8
0
        public void OnIncomingMessage(MessageBusEventArgs message)
        {
            _ai.TrackEvent("Incoming message", new Dictionary <string, string> {
                ["SourcePlugin"] = message.SourcePlugin
            });

            var param = message.TargetArgument as IDictionary <string, object>;

            if (param == null)
            {
                var xml = message.TargetArgument as string;
                param                = new Dictionary <string, object>();
                param["FetchXml"]    = xml;
                param["ConvertOnly"] = false;
            }

            if (_objectExplorer.SelectedConnection == null)
            {
                return;
            }

            var con      = _objectExplorer.SelectedConnection;
            var metadata = _metadata[con];

            var fetch   = DeserializeFetchXml((string)param["FetchXml"]);
            var options = new FetchXml2SqlOptions();

            if ((bool)param["ConvertOnly"])
            {
                options.PreserveFetchXmlOperatorsAsFunctions = false;
            }

            var sql = FetchXml2Sql.Convert(con.ServiceClient, metadata, fetch, options, out _);

            if ((bool)param["ConvertOnly"])
            {
                param["Sql"] = sql;
                OnOutgoingMessage(this, new MessageBusEventArgs(message.SourcePlugin)
                {
                    TargetArgument = null
                });
            }
            else
            {
                CreateQuery(con, "-- Imported from " + message.SourcePlugin + "\r\n\r\n" + sql, message.SourcePlugin == "FetchXML Builder" ? null : message.SourcePlugin);
            }
        }
Example #9
0
        public void Filter()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='firstname' operator='eq' value='Mark' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT firstname, lastname FROM contact WHERE firstname = 'Mark'", NormalizeWhitespace(converted));
        }
Example #10
0
        public void Joins()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <link-entity name='account' from='accountid' to='parentcustomerid'>
                            <attribute name='name' />
                        </link-entity>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT contact.firstname, contact.lastname, account.name FROM contact INNER JOIN account ON contact.parentcustomerid = account.accountid", NormalizeWhitespace(converted));
        }
Example #11
0
        public void EqUserId()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch>
                    <entity name='account'>
                        <attribute name='name' />
                        <filter>
                            <condition attribute='ownerid' operator='eq-userid' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions {
                ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.SqlCalculations
            }, out _);

            Assert.AreEqual("SELECT name FROM account WHERE ownerid = CURRENT_USER", NormalizeWhitespace(converted));
        }
Example #12
0
        public void EqBusinessId()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='parentcustomerid' operator='eq-businessid' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions {
                ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.Literals
            }, out _);

            Assert.AreEqual($"SELECT firstname, lastname FROM contact WHERE parentcustomerid = '{WhoAmIHandler.BusinessUnitId:D}'", NormalizeWhitespace(converted));
        }
Example #13
0
        public void Distinct()
        {
            var context = new XrmFakedContext();

            context.InitializeMetadata(Assembly.GetExecutingAssembly());

            var org      = context.GetOrganizationService();
            var metadata = new AttributeMetadataCache(org);
            var fetch    = @"
                <fetch distinct='true'>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(org, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT DISTINCT firstname, lastname FROM contact", NormalizeWhitespace(converted));
        }
Example #14
0
        public void NextXYearsConversion()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='createdon' operator='next-x-years' value='2' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions {
                ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.Literals
            }, out _);

            Assert.AreEqual($"SELECT firstname, lastname FROM contact WHERE createdon >= '{DateTime.Now:s}' AND createdon < '{DateTime.Today.AddDays(1).AddYears(2):s}'", NormalizeWhitespace(converted));
        }
Example #15
0
        public void ParameterConversion()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='firstname' operator='eq' value='Mark' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions {
                UseParametersForLiterals = true
            }, out var parameters);

            Assert.AreEqual("SELECT firstname, lastname FROM contact WHERE firstname = @firstname", NormalizeWhitespace(converted));
            Assert.AreEqual("Mark", parameters["@firstname"]);
        }
Example #16
0
        public void Disconnected()
        {
            var fetch = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='firstname' operator='eq' value='Mark' />
                            <filter type='or'>
                                <condition attribute='lastname' operator='eq' value='Carrington' />
                                <condition attribute='lastname' operator='eq' value='Twain' />
                            </filter>
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(null, null, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT firstname, lastname FROM contact WHERE firstname = 'Mark' AND (lastname = 'Carrington' OR lastname = 'Twain')", NormalizeWhitespace(converted));
        }
Example #17
0
        public void JoinFilterOr()
        {
            var metadata = new AttributeMetadataCache(_service);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <link-entity name='account' from='accountid' to='parentcustomerid'>
                            <filter type='or'>
                                <condition attribute='name' operator='eq' value='Data8' />
                                <condition attribute='name' operator='eq' value='Microsoft' />
                            </filter>
                        </link-entity>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT contact.firstname, contact.lastname FROM contact INNER JOIN account ON contact.parentcustomerid = account.accountid AND (account.name = 'Data8' OR account.name = 'Microsoft')", NormalizeWhitespace(converted));
        }
Example #18
0
        public void CustomOperator()
        {
            var context = new XrmFakedContext();

            context.InitializeMetadata(Assembly.GetExecutingAssembly());

            var org      = context.GetOrganizationService();
            var metadata = new AttributeMetadataCache(org);
            var fetch    = @"
                <fetch>
                    <entity name='contact'>
                        <attribute name='firstname' />
                        <attribute name='lastname' />
                        <filter>
                            <condition attribute='createdon' operator='last-x-days' value='2' />
                        </filter>
                    </entity>
                </fetch>";

            var converted = FetchXml2Sql.Convert(org, metadata, fetch, new FetchXml2SqlOptions(), out _);

            Assert.AreEqual("SELECT firstname, lastname FROM contact WHERE createdon = lastxdays(2)", NormalizeWhitespace(converted));
        }
Example #19
0
        public void OnIncomingMessage(MessageBusEventArgs message)
        {
            _ai.TrackEvent("Incoming message", new Dictionary <string, string> {
                ["SourcePlugin"] = message.SourcePlugin, ["Source"] = "XrmToolBox"
            });

            var param = message.TargetArgument as IDictionary <string, object>;

            if (param == null)
            {
                var str = message.TargetArgument as string;
                param = new Dictionary <string, object>();

                if (str.StartsWith("<"))
                {
                    param["FetchXml"] = str;
                }
                else
                {
                    param["SQL"] = str;
                }

                param["ConvertOnly"] = false;
            }

            if (_objectExplorer.SelectedConnection == null)
            {
                return;
            }

            var con      = _objectExplorer.SelectedConnection;
            var metadata = _dataSources[con.ConnectionName].Metadata;

            if (param.TryGetValue("FetchXml", out var xml) && xml is string xmlStr && !String.IsNullOrEmpty(xmlStr))
            {
                var fetch   = DeserializeFetchXml(xmlStr);
                var options = new FetchXml2SqlOptions();

                if ((bool)param["ConvertOnly"])
                {
                    options.ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.SqlCalculations;
                }

                _ai.TrackEvent("Convert", new Dictionary <string, string> {
                    ["QueryType"] = "FetchXML", ["Source"] = "XrmToolBox"
                });

                string sql;

                if (Settings.Instance.UseNativeSqlConversion)
                {
                    try
                    {
                        var convertReq = new OrganizationRequest("FetchXMLToSQL")
                        {
                            ["FetchXml"]           = xmlStr,
                            ["SubqueryCompatible"] = true
                        };
                        var convertResp = con.ServiceClient.Execute(convertReq);
                        sql = (string)convertResp["Response"];
                    }
                    catch
                    {
                        sql = FetchXml2Sql.Convert(con.ServiceClient, metadata, fetch, options, out _);
                    }
                }
                else
                {
                    sql = FetchXml2Sql.Convert(con.ServiceClient, metadata, fetch, options, out _);
                }

                if ((bool)param["ConvertOnly"])
                {
                    param["Sql"] = sql;
                    OnOutgoingMessage(this, new MessageBusEventArgs(message.SourcePlugin)
                    {
                        TargetArgument = null
                    });
                }
                else
                {
                    CreateQuery(con, "-- Imported from " + message.SourcePlugin + "\r\n\r\n" + sql);
                }
            }
Example #20
0
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private void Execute(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            try
            {
                _objectExplorer.GetSelectedNodes(out var size, out var nodes);
                var conStr = new SqlConnectionStringBuilder(nodes[0].Connection.ConnectionString);

                var start = ActiveDocument.StartPoint.CreateEditPoint();
                var fetch = start.GetText(ActiveDocument.EndPoint);

                _ai.TrackEvent("Convert", new Dictionary <string, string> {
                    ["QueryType"] = "FetchXML", ["Source"] = "SSMS"
                });

                string sql;
                IDictionary <string, object> paramValues;

                if (Package.Settings.UseNativeSqlConversion)
                {
                    var convertReq = new OrganizationRequest("FetchXMLToSQL")
                    {
                        ["FetchXml"]           = fetch,
                        ["SubqueryCompatible"] = true
                    };
                    var convertResp = ConnectCDS(conStr).Execute(convertReq);
                    sql         = (string)convertResp["Response"];
                    paramValues = new Dictionary <string, object>();
                }
                else
                {
                    sql = FetchXml2Sql.Convert(ConnectCDS(conStr), GetMetadataCache(conStr), fetch, new FetchXml2SqlOptions
                    {
                        ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.SqlCalculations,
                        UseParametersForLiterals   = true,
                        ConvertDateTimeToUtc       = true
                    }, out paramValues);
                }

                ServiceCache.ScriptFactory.CreateNewBlankScript(ScriptType.Sql, ServiceCache.ScriptFactory.CurrentlyActiveWndConnectionInfo.UIConnectionInfo, null);

                var editPoint = ActiveDocument.EndPoint.CreateEditPoint();
                editPoint.Insert("/*\r\nCreated from query:\r\n\r\n");
                editPoint.Insert(fetch);
                editPoint.Insert("\r\n\r\n*/\r\n\r\n");

                foreach (var param in paramValues)
                {
                    string paramType;
                    var    quoteValues = false;

                    switch (param.Value.GetType().Name)
                    {
                    case "Int32":
                        paramType = "int";
                        break;

                    case "Decimal":
                        paramType = "numeric";
                        break;

                    case "DateTime":
                        paramType   = "datetime";
                        quoteValues = true;
                        break;

                    default:
                        paramType   = "nvarchar(max)";
                        quoteValues = true;
                        break;
                    }

                    editPoint.Insert($"DECLARE {param.Key} {paramType} = ");

                    var value = param.Value.ToString();

                    if (param.Value is DateTime dt)
                    {
                        value = dt.ToString("s");
                    }

                    if (quoteValues)
                    {
                        value = "'" + value.Replace("'", "''") + "'";
                    }

                    editPoint.Insert(value + "\r\n");
                }

                if (paramValues.Count > 0)
                {
                    editPoint.Insert("\r\n");
                }

                editPoint.Insert(sql);
            }
            catch (Exception ex)
            {
                VsShellUtilities.LogError("SQL 4 CDS", ex.ToString());
            }
        }
        /// <summary>
        /// Handles the entity retrieve multiple message.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void HandleRetrieveMultipleMessage(PluginExecutionContext context)
        {
            base.HandleRetrieveMultipleMessage(context);

            var query = context.PluginContext.InputParameters["Query"];

            if (query != null)
            {
                var mapper = new GenericMapper(context);

                EntityCollection collection = new EntityCollection();
                string           fetchXml   = string.Empty;
                if (query is QueryExpression qe)
                {
                    var convertRequest = new QueryExpressionToFetchXmlRequest();
                    convertRequest.Query = (QueryExpression)qe;
                    var response = (QueryExpressionToFetchXmlResponse)context.Service.Execute(convertRequest);
                    fetchXml = response.FetchXml;
                }
                else if (query is FetchExpression fe)
                {
                    fetchXml = fe.Query;
                }

                if (!string.IsNullOrEmpty(fetchXml))
                {
                    context.Trace($"Pre FetchXML: {fetchXml}");

                    var metadata = new AttributeMetadataCache(context.Service);
                    var fetch    = Deserialize(fetchXml);
                    mapper.MapFetchXml(fetch);

                    //Store page info before converting
                    int page  = -1;
                    int count = -1;
                    if (!string.IsNullOrEmpty(fetch.page))
                    {
                        page       = Int32.Parse(fetch.page);
                        fetch.page = string.Empty;
                    }

                    if (!string.IsNullOrEmpty(fetch.count))
                    {
                        count       = Int32.Parse(fetch.count);
                        fetch.count = string.Empty;
                    }

                    var sql = FetchXml2Sql.Convert(context.Service, metadata, fetch, new FetchXml2SqlOptions {
                        PreserveFetchXmlOperatorsAsFunctions = false
                    }, out _);

                    sql = mapper.MapVirtualEntityAttributes(sql);
                    context.Trace($"SQL: {sql}");

                    if (page != -1 && count != -1)
                    {
                        collection = this.GetEntitiesFromSql(context, mapper, sql, count, page);
                    }
                    else
                    {
                        collection = this.GetEntitiesFromSql(context, mapper, sql, -1, 1);
                    }
                }
                context.Trace($"Records Returned: {collection.Entities.Count}");
                context.PluginContext.OutputParameters["BusinessEntityCollection"] = collection;
            }
        }