Ejemplo n.º 1
0
        private void RegisterTypes(bool force = false)
        {
            try
            {
                var ctr = TinyIoCContainer.Current;
                _VSOutputWindow.Write(@"If you're using and enjoying QueryFirst, please leave a review!
https://marketplace.visualstudio.com/items?itemName=bbsimonbb.QueryFirst#review-details
");
                //kludge
                if (force == true)
                {
                    ctr.Dispose();
                }
                else if (TinyIoCContainer.Current.CanResolve <IWrapperClassMaker>())
                {
                    _VSOutputWindow.Write("Already registered\n");
                    return;
                }
                List <Assembly> assemblies = new List <Assembly>();

                foreach (Project solutionProject in _dte.Solution.Projects)
                {
                }

                var cFile = _dte.Solution.Projects.Cast <Project>()
                            .SelectMany(p => new FileInfo(p.FullName).Directory?.GetFiles("qfconfig.json")).FirstOrDefault();
                if (cFile != null)
                {
                    //manual read config
                    var config         = JsonConvert.DeserializeObject <QFConfigModel>(File.ReadAllText(cFile.FullName));
                    var helperAssembly = config.HelperAssembly;


                    if (helperAssembly != null && !string.IsNullOrEmpty(helperAssembly))
                    {
                        assemblies.Add(Assembly.LoadFrom(helperAssembly));
                    }
                }

                assemblies.Add(Assembly.GetExecutingAssembly());
                TinyIoCContainer.Current.AutoRegister(assemblies, DuplicateImplementationActions.RegisterSingle, type =>
                {
                    return(type != typeof(Conductor));
                });
                var cndType = assemblies.SelectMany(a => a.SafeGetTypes())
                              .FirstOrDefault(t => typeof(IConductor).IsAssignableFrom(t));
                TinyIoCContainer.Current.Register(typeof(IConductor), cndType).AsMultiInstance();
                // IProvider, for instance, has multiple implementations. To resolve we use the provider name on the connection string,
                // which must correspond to the fully qualified name of the implementation. ie. QueryFirst.Providers.SqlClient for SqlServer

                //_VSOutputWindow.Write("Registered types...\n");
            }
            catch (Exception ex)
            {
                _VSOutputWindow.Write(ex.Message + '\n' + ex.StackTrace);
            }
        }
Ejemplo n.º 2
0
        private void SolutionEvents_Opened()
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            if (!spammed)
            {
                _VSOutputWindow.Write(
                    @"If you're using and enjoying QueryFirst, please leave a review!
https://marketplace.visualstudio.com/items?itemName=bbsimonbb.QueryFirst#review-details
"
                    );
                spammed = true;
            }
            RegisterTypes.Instance.Register(_VSOutputWindow, true);
        }
Ejemplo n.º 3
0
 private void ProcessAllItems(ProjectItems items, VSOutputWindow vsOutputWindow)
 {
     ThreadHelper.ThrowIfNotOnUIThread();
     if (items != null)
     {
         foreach (ProjectItem item in items)
         {
             try
             {
                 if (item.FileNames[1].EndsWith(".sql"))
                 {
                     item.Open();
                     var textDoc = ((TextDocument)item.Document.Object());
                     var text    = textDoc.CreateEditPoint().GetText(textDoc.EndPoint);
                     if (text.Contains("managed by QueryFirst"))
                     {
                         new Conductor(vsOutputWindow, null, null).ProcessOneQuery(item.Document);
                     }
                 }
                 if (item.Kind == "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}") //folder
                 {
                     ProcessAllItems(item.ProjectItems, vsOutputWindow);
                 }
             }
             catch (Exception ex)
             {
                 vsOutputWindow.Write(ex.ToString());
             }
         }
     }
 }
Ejemplo n.º 4
0
        private void RegisterTypes(bool force = false)
        {
            try
            {
                var ctr = TinyIoCContainer.Current;
                _VSOutputWindow.Write("Registering types...\n");
                //kludge
                if (force == true)
                {
                    ctr.Dispose();
                }
                else if (TinyIoCContainer.Current.CanResolve <IWrapperClassMaker>())
                {
                    _VSOutputWindow.Write("Already registered\n");
                    return;
                }
                System.Configuration.KeyValueConfigurationElement helperAssembly = null;
                try
                {
                    ConfigurationAccessor config = new ConfigurationAccessor(_dte, null);
                    helperAssembly = config.AppSettings["QfHelperAssembly"];
                }
                catch (Exception ex)
                {//nobody cares
                }
                List <Assembly> assemblies = new List <Assembly>();
                if (helperAssembly != null && !string.IsNullOrEmpty(helperAssembly.Value))
                {
                    assemblies.Add(Assembly.LoadFrom(helperAssembly.Value));
                }
                assemblies.Add(Assembly.GetExecutingAssembly());
                TinyIoCContainer.Current.AutoRegister(assemblies, DuplicateImplementationActions.RegisterSingle);
                // IProvider, for instance, has multiple implementations. To resolve we use the provider name on the connection string,
                // which must correspond to the fully qualified name of the implementation. ie. QueryFirst.Providers.SqlClient for SqlServer

                _VSOutputWindow.Write("Registered types...\n");
            }
            catch (Exception ex)
            {
                _VSOutputWindow.Write(ex.Message + '\n' + ex.StackTrace);
            }
        }
Ejemplo n.º 5
0
        private void RegisterTypes(bool force = false)
        {
            try
            {
                var ctr = TinyIoCContainer.Current;
                _VSOutputWindow.Write(@"If you're using and enjoying QueryFirst, please leave a review!
https://marketplace.visualstudio.com/items?itemName=bbsimonbb.QueryFirst#review-details
");
                //kludge
                if (force == true)
                {
                    ctr.Dispose();
                }
                else if (TinyIoCContainer.Current.CanResolve <IWrapperClassMaker>())
                {
                    _VSOutputWindow.Write("Already registered\n");
                    return;
                }
                System.Configuration.KeyValueConfigurationElement helperAssembly = null;

                List <Assembly> assemblies = new List <Assembly>();
                if (helperAssembly != null && !string.IsNullOrEmpty(helperAssembly.Value))
                {
                    assemblies.Add(Assembly.LoadFrom(helperAssembly.Value));
                }
                assemblies.Add(Assembly.GetExecutingAssembly());
                TinyIoCContainer.Current.AutoRegister(assemblies, DuplicateImplementationActions.RegisterSingle);
                // IProvider, for instance, has multiple implementations. To resolve we use the provider name on the connection string,
                // which must correspond to the fully qualified name of the implementation. ie. QueryFirst.Providers.SqlClient for SqlServer

                //_VSOutputWindow.Write("Registered types...\n");
            }
            catch (Exception ex)
            {
                _VSOutputWindow.Write(ex.Message + '\n' + ex.StackTrace);
            }
        }
Ejemplo n.º 6
0
        public void ProcessOneQuery(Document queryDoc)
        {
            _tiny = TinyIoCContainer.Current;
            _ctx.InitForQuery(queryDoc);
            // Test this! If I can get source control exclusions working, team members won't get the generated file.

            if (!File.Exists(_ctx.GeneratedClassFullFilename))
            {
                File.Create(_ctx.GeneratedClassFullFilename);
            }
            if (GetItemByFilename(queryDoc.ProjectItem, _ctx.GeneratedClassFullFilename) != null)
            {
                queryDoc.ProjectItem.Collection.AddFromFile(_ctx.GeneratedClassFullFilename);
            }
            // copy namespace of generated partial class from user partial class
            // backward compatible...
            var textDoc = ((TextDocument)_ctx.QueryDoc.Object());

            textDoc.ReplacePattern("--designTime", "-- designTime");
            textDoc.ReplacePattern("--endDesignTime", "-- endDesignTime");
            try
            {
                if (string.IsNullOrEmpty(_ctx.Config.DefaultConnection))
                {
                    _vsOutputWindow.Write(@"QueryFirst would like to help you, but you need to tell it where your DB is.
Breaking change in 1.0.0: QueryFirst now has it's own config file. You need to create qfconfig.json beside or above your query 
or put --QfDefaultConnection=myConnectionString somewhere in your query file.
See the Readme section at https://marketplace.visualstudio.com/items?itemName=bbsimonbb.QueryFirst    
");
                    return; // nothing to be done
                }
                if (!_tiny.CanResolve <IProvider>(_ctx.Config.Provider))
                {
                    _vsOutputWindow.Write(string.Format(
                                              @"No Implementation of IProvider for providerName {0}. 
The query {1} may not run and the wrapper has not been regenerated.",
                                              _ctx.Config.Provider, _ctx.BaseName
                                              ));
                    return;
                }
                // Use QueryFirst within QueryFirst !
                // ToDo, to make this work with Postgres, store as ConnectionStringSettings with provider name.
                QfRuntimeConnection.CurrentConnectionString = _ctx.Config.DefaultConnection;


                var matchInsert = Regex.Match(_ctx.Query.Text, "^insert\\s+into\\s+(?<tableName>\\w+)\\.\\.\\.", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                var matchUpdate = Regex.Match(_ctx.Query.Text, "^update\\s+(?<tableName>\\w+)\\.\\.\\.", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                if (matchInsert.Success)
                {
                    var statement = new ScaffoldInsert().ExecuteScalar(matchInsert.Groups["tableName"].Value);
                    if (string.IsNullOrEmpty(statement))
                    {
                        _vsOutputWindow.Write("Unknown problem generating insert.\n");
                    }
                    else
                    {
                        var ep = textDoc.CreateEditPoint();
                        ep.ReplaceText(_ctx.Query.Text.Length, statement, 0);
                        //ctx.QueryDoc.Save();
                    }
                }
                else if (matchUpdate.Success)
                {
                    var statement = new ScaffoldUpdate().ExecuteScalar(matchUpdate.Groups["tableName"].Value);
                    if (string.IsNullOrEmpty(statement))
                    {
                        _vsOutputWindow.Write("Unknown problem generating update.\n");
                    }
                    else
                    {
                        var ep = textDoc.CreateEditPoint();
                        ep.ReplaceText(_ctx.Query.Text.Length, statement, 0);
                        //ctx.QueryDoc.Save();
                    }
                }
                else
                {
                    // Execute query
                    try
                    {
                        // also called in the bowels of schema fetching, for Postgres, because no notion of declarations.
                        try
                        {
                            var undeclared           = _ctx.Provider.FindUndeclaredParameters(_ctx.Query.Text, _ctx.Config.DefaultConnection);
                            var newParamDeclarations = _ctx.Provider.ConstructParameterDeclarations(undeclared);
                            if (!string.IsNullOrEmpty(newParamDeclarations))
                            {
                                _ctx.Query.ReplacePattern("-- endDesignTime", newParamDeclarations + "-- endDesignTime");
                            }
                        }
                        catch (SqlException ex)
                        {
                            if (ex.Message.Contains("sp_describe_undeclared_parameters"))
                            {
                                _vsOutputWindow.Write("Unable to find undeclared parameters. You will have to do this yourself.\n");
                            }
                            else
                            {
                                throw;
                            }
                        }

                        _ctx.ResultFields = _ctx.SchemaFetcher.GetFields(_ctx.Config.DefaultConnection, _ctx.Config.Provider, _ctx.Query.Text);
                    }
                    catch (Exception ex)
                    {
                        StringBuilder bldr = new StringBuilder();
                        bldr.AppendLine("Error running query.");
                        bldr.AppendLine();
                        bldr.AppendLine("/*The last attempt to run this query failed with the following error. This class is no longer synced with the query");
                        bldr.AppendLine("You can compile the class by deleting this error information, but it will likely generate runtime errors.");
                        bldr.AppendLine("-----------------------------------------------------------");
                        bldr.AppendLine(ex.Message);
                        bldr.AppendLine("-----------------------------------------------------------");
                        bldr.AppendLine(ex.StackTrace);
                        bldr.AppendLine("*/");
                        File.AppendAllText(_ctx.GeneratedClassFullFilename, bldr.ToString());
                        throw;
                    }
                    _ctx.QueryHasRun = true;
                    StringBuilder Code = new StringBuilder();

                    var wrapper = _tiny.Resolve <IWrapperClassMaker>();
                    var results = _tiny.Resolve <IResultClassMaker>();

                    Code.Append(wrapper.StartNamespace(_ctx));
                    Code.Append(wrapper.Usings(_ctx));
                    if (_ctx.Config.MakeSelfTest)
                    {
                        Code.Append(wrapper.SelfTestUsings(_ctx));
                    }
                    if (_ctx.ResultFields != null && _ctx.ResultFields.Count > 0)
                    {
                        Code.Append(results.Usings());
                    }
                    Code.Append(wrapper.MakeInterface(_ctx));
                    Code.Append(wrapper.StartClass(_ctx));
                    Code.Append(wrapper.MakeExecuteNonQueryWithoutConn(_ctx));
                    Code.Append(wrapper.MakeExecuteNonQueryWithConn(_ctx));
                    Code.Append(wrapper.MakeGetCommandTextMethod(_ctx));
                    Code.Append(_ctx.Provider.MakeAddAParameter(_ctx));

                    if (_ctx.Config.MakeSelfTest)
                    {
                        Code.Append(wrapper.MakeSelfTestMethod(_ctx));
                    }
                    if (_ctx.ResultFields != null && _ctx.ResultFields.Count > 0)
                    {
                        Code.Append(wrapper.MakeExecuteWithoutConn(_ctx));
                        Code.Append(wrapper.MakeExecuteWithConn(_ctx));
                        Code.Append(wrapper.MakeGetOneWithoutConn(_ctx));
                        Code.Append(wrapper.MakeGetOneWithConn(_ctx));
                        Code.Append(wrapper.MakeExecuteScalarWithoutConn(_ctx));
                        Code.Append(wrapper.MakeExecuteScalarWithConn(_ctx));

                        Code.Append(wrapper.MakeCreateMethod(_ctx));
                        Code.Append(wrapper.MakeOtherMethods(_ctx));
                        Code.Append(wrapper.CloseClass(_ctx));
                        Code.Append(results.StartClass(_ctx));
                        foreach (var fld in _ctx.ResultFields)
                        {
                            Code.Append(results.MakeProperty(fld));
                        }
                    }
                    Code.Append(results.CloseClass()); // closes wrapper class if no results !
                    Code.Append(wrapper.CloseNamespace(_ctx));
                    //File.WriteAllText(ctx.GeneratedClassFullFilename, Code.ToString());
                    _ctx.PutCodeHere.WriteAndFormat(Code.ToString());
                    var partialClassFile = GetItemByFilename(_ctx.QueryDoc.ProjectItem, _ctx.CurrDir + _ctx.BaseName + "Results.cs");
                    new BackwardCompatibility().InjectPOCOFactory(_ctx, partialClassFile);
                    _vsOutputWindow.Write(Environment.NewLine + "QueryFirst generated wrapper class for " + _ctx.BaseName + ".sql");
                }
            }
            catch (Exception ex)
            {
                _vsOutputWindow.Write(ex.TellMeEverything());
            }
        }
Ejemplo n.º 7
0
        public void ProcessOneQuery(Document queryDoc)
        {
            try
            {
                ThreadHelper.ThrowIfNotOnUIThread();

                _state    = new State();
                _queryDoc = queryDoc;
                _item     = queryDoc.ProjectItem;

                ProcessUpToStep4(queryDoc, ref _state);

                // Test this! If I can get source control exclusions working, team members won't get the generated file.
                if (!File.Exists(_state._1GeneratedClassFullFilename))
                {
                    var _ = File.Create(_state._1GeneratedClassFullFilename);
                    _.Dispose();
                }
                if (GetItemByFilename(queryDoc.ProjectItem, _state._1GeneratedClassFullFilename) != null)
                {
                    queryDoc.ProjectItem.Collection.AddFromFile(_state._1GeneratedClassFullFilename);
                }

                // We have the config, we can instantiate our provider...
                if (_tiny.CanResolve <IProvider>(_state._4Config.provider))
                {
                    _provider = _tiny.Resolve <IProvider>(_state._4Config.provider);
                }
                else
                {
                    _vsOutputWindow.Write(@"After resolving the config, we have no provider\n");
                }



                if (string.IsNullOrEmpty(_state._4Config.defaultConnection))
                {
                    _vsOutputWindow.Write(@"No design time connection string. You need to create qfconfig.json beside or above your query 
or put --QfDefaultConnection=myConnectionString somewhere in your query file.
See the Readme section at https://marketplace.visualstudio.com/items?itemName=bbsimonbb.QueryFirst    
");
                    return; // nothing to be done
                }
                if (!_tiny.CanResolve <IProvider>(_state._4Config.provider))
                {
                    _vsOutputWindow.Write(string.Format(
                                              @"No Implementation of IProvider for providerName {0}. 
The query {1} may not run and the wrapper has not been regenerated.\n",
                                              _state._4Config.provider, _state._1BaseName
                                              ));
                    return;
                }
                // Scaffold inserts and updates
                _tiny.Resolve <_5ScaffoldUpdateOrInsert>().Go(ref _state);

                if (_state._3InitialQueryText != _state._5QueryAfterScaffolding)
                {
                    var textDoc = ((TextDocument)queryDoc.Object());
                    var ep      = textDoc.CreateEditPoint();
                    ep.ReplaceText(_state._3InitialQueryText.Length, _state._5QueryAfterScaffolding, 0);
                }


                // Execute query
                try
                {
                    new _6FindUndeclaredParameters(_provider).Go(ref _state, out string outputMessage);
                    // if message returned, write it to output.
                    if (!string.IsNullOrEmpty(outputMessage))
                    {
                        _vsOutputWindow.Write(outputMessage);
                    }
                    // if undeclared params were found, add them to the .sql
                    if (!string.IsNullOrEmpty(_state._6NewParamDeclarations))
                    {
                        ReplacePattern("-- endDesignTime", _state._6NewParamDeclarations + "-- endDesignTime");
                    }

                    new _7RunQueryAndGetResultSchema(new AdoSchemaFetcher(), _provider).Go(ref _state);
                    new _8ParseOrFindDeclaredParams(_provider).Go(ref _state);
                }
                catch (Exception ex)
                {
                    StringBuilder bldr = new StringBuilder();
                    bldr.AppendLine("Error running query.");
                    bldr.AppendLine();
                    bldr.AppendLine("/*The last attempt to run this query failed with the following error. This class is no longer synced with the query");
                    bldr.AppendLine("You can compile the class by deleting this error information, but it will likely generate runtime errors.");
                    bldr.AppendLine("-----------------------------------------------------------");
                    bldr.AppendLine(ex.Message);
                    bldr.AppendLine("-----------------------------------------------------------");
                    bldr.AppendLine(ex.StackTrace);
                    bldr.AppendLine("*/");
                    File.AppendAllText(_state._1GeneratedClassFullFilename, bldr.ToString());
                    throw;
                }

                // dump state for reproducing issues
#if DEBUG
                using (var ms = new MemoryStream())
                {
                    var ser = new DataContractJsonSerializer(typeof(State));
                    ser.WriteObject(ms, _state);
                    byte[] json = ms.ToArray();
                    ms.Close();
                    File.WriteAllText(_state._1CurrDir + "qfDumpState.json", Encoding.UTF8.GetString(json, 0, json.Length));
                }
#endif

                var code = GenerateCode(_state);
                //File.WriteAllText(ctx.GeneratedClassFullFilename, Code.ToString());
                var genFile = GetItemByFilename(queryDoc.ProjectItem, _state._1GeneratedClassFullFilename);
                WriteAndFormat(genFile, code);
                // what was this for ????
                //var partialClassFile = GetItemByFilename(_ctx.QueryDoc.ProjectItem, _state._1CurrDir + _state._1BaseName + "Results.cs");
                _vsOutputWindow.Write("QueryFirst generated wrapper class for " + _state._1BaseName + ".sql" + Environment.NewLine);
            }
            catch (Exception ex)
            {
                _vsOutputWindow.Write(ex.TellMeEverything());
            }
        }
Ejemplo n.º 8
0
        public void ProcessOneQuery(Document queryDoc)
        {
            _tiny = TinyIoCContainer.Current;
            ctx   = new CodeGenerationContext(queryDoc);

            // Test this! If I can get source control exclusions working, team members won't get the generated file.

            if (!File.Exists(ctx.GeneratedClassFullFilename))
            {
                File.Create(ctx.GeneratedClassFullFilename);
            }
            if (GetItemByFilename(queryDoc.ProjectItem.Collection, ctx.GeneratedClassFullFilename) != null)
            {
                queryDoc.ProjectItem.Collection.AddFromFile(ctx.GeneratedClassFullFilename);
            }
            // copy namespace of generated partial class from user partial class
            // backward compatible...
            var textDoc = ((TextDocument)ctx.QueryDoc.Object());

            textDoc.ReplacePattern("--designTime", "-- designTime");
            textDoc.ReplacePattern("--endDesignTime", "-- endDesignTime");
            try
            {
                if (!ctx.DesignTimeConnectionString.IsPresent)
                {
                    _vsOutputWindow.Write(@"QueryFirst would like to help you, but you need to tell it where your DB is.
    You can specify the design time connection string in your app or web.config or directly in the query file.
    Add these lines to your app or web.config. providerName should be one of System.Data.SqlClient, Npgsql MySql.Data.MySqlClient.
    <connectionStrings>
        <add name=""QfDefaultConnection"" connectionString=""Data Source = localhost; Initial Catalog = NORTHWND; Integrated Security = SSPI; "" providerName=""System.Data.SqlClient"" />
    </ connectionStrings >
    or put --QfDefaultConnection=myConnectionString somewhere in your query file.
");
                    return; // nothing to be done
                }
                if (!ctx.DesignTimeConnectionString.IsProviderValid)
                {
                    _vsOutputWindow.Write(string.Format(
                                              @"No Implementation of IProvider for providerName {0}. 
The query {1} may not run and the wrapper has not been regenerated.",
                                              ctx.DesignTimeConnectionString.v.ProviderName, ctx.BaseName
                                              ));
                }
                // Use QueryFirst within QueryFirst !
                // ToDo, to make this work with Postgres, store as ConnectionStringSettings with provider name.
                QfRuntimeConnection.CurrentConnectionString = ctx.DesignTimeConnectionString.v.ConnectionString;

                var makeSelfTest = ctx.ProjectConfig?.AppSettings["QfMakeSelfTest"] != null && bool.Parse(ctx.ProjectConfig.AppSettings["QfMakeSelfTest"].Value);

                var matchInsert = Regex.Match(ctx.Query.Text, "^insert\\s+into\\s+(?<tableName>\\w+)\\.\\.\\.", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                var matchUpdate = Regex.Match(ctx.Query.Text, "^update\\s+(?<tableName>\\w+)\\.\\.\\.", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                if (matchInsert.Success)
                {
                    var statement = new ScaffoldInsert().ExecuteScalar(matchInsert.Groups["tableName"].Value);
                    var ep        = textDoc.CreateEditPoint();
                    ep.ReplaceText(ctx.Query.Text.Length, statement, 0);
                    //ctx.QueryDoc.Save();
                }
                else if (matchUpdate.Success)
                {
                    var statement = new ScaffoldUpdate().ExecuteScalar(matchUpdate.Groups["tableName"].Value);
                    var ep        = textDoc.CreateEditPoint();
                    ep.ReplaceText(ctx.Query.Text.Length, statement, 0);
                    //ctx.QueryDoc.Save();
                }
                else
                {
                    // Execute query
                    try
                    {
                        // also called in the bowels of schema fetching, for Postgres, because no notion of declarations.
                        try
                        {
                            var undeclared           = ctx.Provider.FindUndeclaredParameters(ctx.Query.Text);
                            var newParamDeclarations = ctx.Provider.ConstructParameterDeclarations(undeclared);
                            if (!string.IsNullOrEmpty(newParamDeclarations))
                            {
                                ctx.Query.ReplacePattern("-- endDesignTime", newParamDeclarations + "-- endDesignTime");
                            }
                        }
                        catch (SqlException ex)
                        {
                            if (ex.Message.Contains("sp_describe_undeclared_parameters"))
                            {
                                _vsOutputWindow.Write("Unable to find undeclared parameters. You will have to do this yourself.\n");
                            }
                            else
                            {
                                throw;
                            }
                        }

                        ctx.ResultFields = ctx.Hlpr.GetFields(ctx.DesignTimeConnectionString.v, ctx.Query.Text);
                    }
                    catch (Exception ex)
                    {
                        StringBuilder bldr = new StringBuilder();
                        bldr.AppendLine("Error running query.");
                        bldr.AppendLine();
                        bldr.AppendLine("/*The last attempt to run this query failed with the following error. This class is no longer synced with the query");
                        bldr.AppendLine("You can compile the class by deleting this error information, but it will likely generate runtime errors.");
                        bldr.AppendLine("-----------------------------------------------------------");
                        bldr.AppendLine(ex.Message);
                        bldr.AppendLine("-----------------------------------------------------------");
                        bldr.AppendLine(ex.StackTrace);
                        bldr.AppendLine("*/");
                        File.AppendAllText(ctx.GeneratedClassFullFilename, bldr.ToString());
                        throw;
                    }
                    ctx.QueryHasRun = true;
                    StringBuilder Code = new StringBuilder();

                    var wrapper = _tiny.Resolve <IWrapperClassMaker>();
                    var results = _tiny.Resolve <IResultClassMaker>();

                    Code.Append(wrapper.StartNamespace(ctx));
                    Code.Append(wrapper.Usings(ctx));
                    if (makeSelfTest)
                    {
                        Code.Append(wrapper.SelfTestUsings(ctx));
                    }
                    if (ctx.ResultFields != null && ctx.ResultFields.Count > 0)
                    {
                        Code.Append(results.Usings());
                    }
                    Code.Append(wrapper.MakeInterface(ctx));
                    Code.Append(wrapper.StartClass(ctx));
                    Code.Append(wrapper.MakeExecuteNonQueryWithoutConn(ctx));
                    Code.Append(wrapper.MakeExecuteNonQueryWithConn(ctx));
                    Code.Append(wrapper.MakeGetCommandTextMethod(ctx));
                    Code.Append(ctx.Provider.MakeAddAParameter(ctx));

                    if (makeSelfTest)
                    {
                        Code.Append(wrapper.MakeSelfTestMethod(ctx));
                    }
                    if (ctx.ResultFields != null && ctx.ResultFields.Count > 0)
                    {
                        Code.Append(wrapper.MakeExecuteWithoutConn(ctx));
                        Code.Append(wrapper.MakeExecuteWithConn(ctx));
                        Code.Append(wrapper.MakeGetOneWithoutConn(ctx));
                        Code.Append(wrapper.MakeGetOneWithConn(ctx));
                        Code.Append(wrapper.MakeExecuteScalarWithoutConn(ctx));
                        Code.Append(wrapper.MakeExecuteScalarWithConn(ctx));

                        Code.Append(wrapper.MakeCreateMethod(ctx));
                        Code.Append(wrapper.MakeOtherMethods(ctx));
                        Code.Append(wrapper.CloseClass(ctx));
                        Code.Append(results.StartClass(ctx));
                        foreach (var fld in ctx.ResultFields)
                        {
                            Code.Append(results.MakeProperty(fld));
                        }
                    }
                    Code.Append(results.CloseClass()); // closes wrapper class if no results !
                    Code.Append(wrapper.CloseNamespace(ctx));
                    //File.WriteAllText(ctx.GeneratedClassFullFilename, Code.ToString());
                    ctx.PutCodeHere.WriteAndFormat(Code.ToString());
                    var partialClassFile = GetItemByFilename(ctx.QueryDoc.ProjectItem.ProjectItems, ctx.CurrDir + ctx.BaseName + "Results.cs");
                    new BackwardCompatibility().InjectPOCOFactory(ctx, partialClassFile);
                    _vsOutputWindow.Write(Environment.NewLine + "QueryFirst generated wrapper class for " + ctx.BaseName + ".sql");
                }
            }
            catch (Exception ex)
            {
                _vsOutputWindow.Write(ex.TellMeEverything());
            }
        }