diff --git a/.gitignore b/.gitignore index e4872dbc..ee76c2a6 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ Test *.nupkg *.msi *.chm +.vs /Tools /build.txt diff --git a/Source/MSBuild.Community.Tasks/SqlExecute.cs b/Source/MSBuild.Community.Tasks/SqlExecute.cs index 52078f26..705a22be 100644 --- a/Source/MSBuild.Community.Tasks/SqlExecute.cs +++ b/Source/MSBuild.Community.Tasks/SqlExecute.cs @@ -36,202 +36,235 @@ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. using System.Data.SqlClient; using System.IO; - - namespace MSBuild.Community.Tasks { - /// - /// Executes a SQL command. - /// - /// - /// Execute a SQL command against a database. Target attributes to set: - /// ConnectionString (required), Command (required, the SQL to execute), - /// SelectMode (NonQuery, Scalar, or ScalarXml, default is NonQuery), - /// OutputFile (required when SelectMode is Scalar or ScalarXml). - /// - /// Note: ScalarXml was created because of the 2033 byte limit on the sql return. - /// See http://aspnetresources.com/blog/executescalar_truncates_xml.aspx for details. - /// - /// - /// Example of returning a count of items in a table. Uses the default SelectMode of NonQuery. - /// - /// ]]> - /// - /// Example of returning the items of a table in an xml format. - /// - /// ]]> - /// - public class SqlExecute : Task - { - - private const string NONQUERY = "NonQuery"; - private const string SCALAR = "Scalar"; - private const string SCALARXML = "ScalarXml"; - - /// - /// When overridden in a derived class, executes the task. - /// - /// - /// true if the task successfully executed; otherwise, false. - /// - public override bool Execute() - { - SqlConnection con = null; - SqlCommand cmd = null; - _result = -1; - - try - { - con = new SqlConnection(ConnectionString); - cmd = new SqlCommand(Command, con); - cmd.CommandTimeout = CommandTimeout; - con.Open(); - - switch (SelectMode) - { - case SCALAR: - if (!IsOutputFileSpecified(SCALAR)) - { - return false; - } - object scalar = cmd.ExecuteScalar(); - Log.LogMessage("Successfully executed SQL command."); - File.WriteAllText(this.OutputFile, scalar.ToString()); - break; - case SCALARXML: - if (!IsOutputFileSpecified(SCALARXML)) - { - return false; - } - - System.Xml.XmlReader rdr = cmd.ExecuteXmlReader(); - using (TextWriter tw = new StreamWriter(OutputFile)) - { - while (rdr.Read()) - { - tw.Write(rdr.ReadOuterXml()); - } - tw.Close(); - } - break; - case NONQUERY: - _result = cmd.ExecuteNonQuery(); - Log.LogMessage("Successfully executed SQL command with result = : " + _result.ToString()); - break; - default: - Log.LogError("Unrecognized SelectMode: " + SelectMode); - return false; - } - return true; - } - catch (Exception ex) - { - Log.LogError("Error executing SQL command: {0}\n{1}", Command, ex.Message); - return false; - } - finally - { - if (con != null) - con.Close(); - } - } - - #region private decls - private string _conStr; - private string _cmd; - private string _mode; - private int _result; - private string _output; - private int _commandTimeout; - #endregion - - /// - /// The connection string - /// - [Required] - public string ConnectionString - { - get { return _conStr; } - set { _conStr = value; } - } - - /// - /// The command to execute - /// - [Required] - public string Command - { - get { return _cmd; } - set { _cmd = value; } - } - - /// - /// Command Timeout - /// - /// Defaults to 30 seconds. Set to 0 for an infinite timeout period. - [DefaultValue(30)] - public int CommandTimeout - { - get { return _commandTimeout; } - set { _commandTimeout = value; } - } - - /// - /// The SQL Selection Mode. Set to NonQuery, Scalar, or ScalarXml. Default is NonQuery. - /// - public string SelectMode - { - get - { - if (_mode == null) - { - return NONQUERY; - } - else - { - return _mode; - } - } - set { _mode = value; } - } - - /// - /// The file name to write to - /// - public string OutputFile - { - get { return _output; } - set { _output = value; } - } - - /// - /// Determines if an output file was specified. - /// - private bool IsOutputFileSpecified(string selectionMode) - { - if (this.OutputFile == null || this.OutputFile == string.Empty) - { - Log.LogError("When using SelectMode=\"{0}\" you must specify an OutputFile.", selectionMode); - return false; - } - - return true; - } - - - /// - /// Output the return count/value - /// - [Output] - public int Result - { - get { return _result; } - } - } + /// + /// Executes a SQL command. + /// + /// + /// Execute a SQL command against a database. Target attributes to set: + /// ConnectionString (required), Command (required, the SQL to execute), + /// SelectMode (NonQuery, Scalar, or ScalarXml, default is NonQuery), + /// OutputFile (required when SelectMode is Scalar or ScalarXml). + /// + /// Note: ScalarXml was created because of the 2033 byte limit on the sql return. + /// See http://aspnetresources.com/blog/executescalar_truncates_xml.aspx for details. + /// + /// + /// Example of returning a count of items in a table. Uses the default SelectMode of NonQuery. + /// + /// ]]> + /// + /// Example of returning the items of a table in an xml format. + /// + /// ]]> + /// + public class SqlExecute : Task + { + private const string NONQUERY = "NonQuery"; + private const string SCALAR = "Scalar"; + private const string SCALARXML = "ScalarXml"; + + #region Methods + + #region Public + + /// + /// When overridden in a derived class, executes the task. + /// + /// + /// true if the task successfully executed; otherwise, false. + /// + public override bool Execute() + { + SqlConnection con = null; + SqlCommand cmd = null; + _result = -1; + + try + { + con = new SqlConnection(ConnectionString); + cmd = new SqlCommand(Command, con); + cmd.CommandTimeout = CommandTimeout; + con.Open(); + + switch (SelectMode) + { + case SCALAR: + object scalar = cmd.ExecuteScalar(); + + ResultBuilder = new StringBuilder(scalar.ToString()); + WriteOutputToFileIfSpecified(); + + Log.LogMessage("Successfully executed SQL command."); + break; + + case SCALARXML: + System.Xml.XmlReader rdr = cmd.ExecuteXmlReader(); + + ResultBuilder = new StringBuilder(); + + using (TextWriter outputWriter = new StringWriter(ResultBuilder)) + { + while (rdr.Read()) + { + outputWriter.Write(rdr.ReadOuterXml()); + } + outputWriter.Close(); + + } + + WriteOutputToFileIfSpecified(); + + break; + case NONQUERY: + _result = cmd.ExecuteNonQuery(); + Log.LogMessage("Successfully executed SQL command with result = : " + _result.ToString()); + break; + default: + Log.LogError("Unrecognized SelectMode: " + SelectMode); + return false; + } + return true; + } + catch (Exception ex) + { + Log.LogError("Error executing SQL command: {0}\n{1}", Command, ex.Message); + return false; + } + finally + { + if (con != null) + con.Close(); + } + } + + #endregion + + #region Private + + private bool IsOutputFileSpecified() + { + return !string.IsNullOrWhiteSpace(OutputFile); + } + + private void WriteOutputToFileIfSpecified() + { + if (IsOutputFileSpecified()) + { + File.WriteAllText(this.OutputFile, ResultBuilder.ToString()); + } + } + + #endregion + #endregion + + #region Properties + + #region Public parameters + + /// + /// The connection string + /// + [Required] + public string ConnectionString + { + get { return _conStr; } + set { _conStr = value; } + } + + /// + /// The command to execute + /// + [Required] + public string Command + { + get { return _cmd; } + set { _cmd = value; } + } + + /// + /// Command Timeout + /// + /// Defaults to 30 seconds. Set to 0 for an infinite timeout period. + [DefaultValue(30)] + public int CommandTimeout + { + get { return _commandTimeout; } + set { _commandTimeout = value; } + } + + /// + /// The SQL Selection Mode. Set to NonQuery, Scalar, or ScalarXml. Default is NonQuery. + /// + public string SelectMode + { + get + { + if (_mode == null) + { + return NONQUERY; + } + else + { + return _mode; + } + } + set { _mode = value; } + } + + /// + /// The file name to write to + /// + public string OutputFile + { + get { return _output; } + set { _output = value; } + } + + /// + /// Output the scalar/ xmlscalar result output if no output file specified + /// + [Output] + public string ResultValue + { + get + { + return ResultBuilder.ToString(); + } + } + + /// + /// Output the return count/value + /// + [Output] + public int Result + { + get { return _result; } + } + + #endregion + + #region Private + private StringBuilder ResultBuilder { get; set; } + + #endregion + + #endregion + + #region private decls + private string _conStr; + private string _cmd; + private string _mode; + private int _result; + private string _output; + private int _commandTimeout; + #endregion + } }