From: Michael D. <mik...@us...> - 2005-01-30 19:39:25
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv308/NHibernate/SqlCommand Modified Files: Parameter.cs ParameterLength.cs ParameterPrecisionScale.cs QuerySelect.cs SqlString.cs Log Message: Parameter classes are now immutable. All values must be set in the ctor. Index: Parameter.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/Parameter.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Parameter.cs 31 Dec 2004 22:25:00 -0000 1.12 --- Parameter.cs 30 Jan 2005 19:39:13 -0000 1.13 *************** *** 9,13 **** { /// <summary> ! /// A lightweight object to hold what later will be converted into an IDbParameter /// for an IDbCommand. /// </summary> --- 9,13 ---- { /// <summary> ! /// An immutable Parameter that later will be converted into an IDbParameter /// for an IDbCommand. /// </summary> *************** *** 15,41 **** public class Parameter : ICloneable { ! private string tableAlias; ! private string name; private SqlType _sqlType; ! /// <summary></summary> public string Name { ! get { return name; } ! set { this.name = value; } } ! /// <summary></summary> public string TableAlias { ! get { return tableAlias; } ! set { this.tableAlias = value; } } ! /// <summary></summary> public SqlType SqlType { get { return _sqlType; } - set { _sqlType = value; } } --- 15,89 ---- public class Parameter : ICloneable { ! private string _tableAlias; ! private string _name; private SqlType _sqlType; ! /// <summary> ! /// Initializes a new instance of <see cref="Parameter"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! public Parameter(string name) ! : this( name, null, null ) ! { ! } ! ! /// <summary> ! /// Initializes a new instance of <see cref="Parameter"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="sqlType">The <see cref="SqlType"/> to create the parameter for.</param> ! public Parameter(string name, SqlType sqlType) ! : this( name, null, sqlType ) ! { ! } ! ! /// <summary> ! /// Initializes a new instance of <see cref="Parameter"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="tableAlias">The Alias to use for the table.</param> ! /// <param name="sqlType">The <see cref="SqlType"/> to create the parameter for.</param> ! public Parameter(string name, string tableAlias, SqlType sqlType) ! { ! _name = name; ! _tableAlias = tableAlias; ! _sqlType = sqlType; ! } ! ! /// <summary> ! /// Gets the name of the Parameter. ! /// </summary> ! /// <value>The name of the Parameter.</value> public string Name { ! get { return _name; } } ! /// <summary> ! /// Gets the alias for the table in the Sql statement. ! /// </summary> ! /// <value> ! /// The alias for the table in the Sql statement. ! /// </value> ! /// <remarks> ! /// TODO: Determine if this is even needed - it is not used anywhere ! /// and is just extra junk. ! /// </remarks> public string TableAlias { ! get { return _tableAlias; } } ! /// <summary> ! /// Gets the <see cref="SqlType"/> that defines the specifics of ! /// the IDbDataParameter. ! /// </summary> ! /// <value> ! /// The <see cref="SqlType"/> that defines the specifics of ! /// the IDbDataParameter. ! /// </value> public SqlType SqlType { get { return _sqlType; } } *************** *** 47,51 **** /// <param name="type">The IType to turn into Parameters</param> /// <param name="factory"></param> ! /// <returns>An Array of IParameter objects</returns> public static Parameter[ ] GenerateParameters( ISessionFactoryImplementor factory, string[ ] columnNames, IType type ) { --- 95,99 ---- /// <param name="type">The IType to turn into Parameters</param> /// <param name="factory"></param> ! /// <returns>An Array of <see cref="Parameter"/> objects</returns> public static Parameter[ ] GenerateParameters( ISessionFactoryImplementor factory, string[ ] columnNames, IType type ) { *************** *** 61,65 **** /// <param name="columnNames">The names of the Columns that compose the IType</param> /// <param name="type">The IType to turn into Parameters</param> ! /// <returns>An Array of IParameter objects</returns> public static Parameter[ ] GenerateParameters( ISessionFactoryImplementor factory, string tableAlias, string[ ] columnNames, IType type ) { --- 109,113 ---- /// <param name="columnNames">The names of the Columns that compose the IType</param> /// <param name="type">The IType to turn into Parameters</param> ! /// <returns>An Array of <see cref="Parameter"/> objects</returns> public static Parameter[ ] GenerateParameters( ISessionFactoryImplementor factory, string tableAlias, string[ ] columnNames, IType type ) { *************** *** 72,98 **** if( sqlTypes[ i ].LengthDefined ) { ! ParameterLength param = new ParameterLength(); ! param.Length = sqlTypes[ i ].Length; parameters[ i ] = param; } else if( sqlTypes[ i ].PrecisionDefined ) { ! ParameterPrecisionScale param = new ParameterPrecisionScale(); ! param.Precision = sqlTypes[ i ].Precision; ! param.Scale = sqlTypes[ i ].Scale; parameters[ i ] = param; } else { ! parameters[ i ] = new Parameter(); } - - parameters[ i ].Name = columnNames[ i ]; - parameters[ i ].TableAlias = tableAlias; - parameters[ i ].SqlType = sqlTypes[ i ]; - } - return parameters; } --- 120,137 ---- if( sqlTypes[ i ].LengthDefined ) { ! ParameterLength param = new ParameterLength( columnNames[i], tableAlias, sqlTypes[i] ); parameters[ i ] = param; } else if( sqlTypes[ i ].PrecisionDefined ) { ! ParameterPrecisionScale param = new ParameterPrecisionScale( columnNames[i], tableAlias, sqlTypes[i] ); parameters[ i ] = param; } else { ! parameters[ i ] = new Parameter( columnNames[i], tableAlias, sqlTypes[i] ); } } return parameters; } *************** *** 101,108 **** /// <summary> ! /// /// </summary> ! /// <param name="obj"></param> ! /// <returns></returns> public override bool Equals( object obj ) { --- 140,154 ---- /// <summary> ! /// Determines wether this instance and the specified object ! /// are the same Type and have the same values. /// </summary> ! /// <param name="obj">An object to compare to this instance.</param> ! /// <returns> ! /// <c>true</c> if the object is a Parameter (not a subclass) and has the ! /// same values. ! /// </returns> ! /// <remarks> ! /// Each subclass needs to implement their own <c>Equals</c>. ! /// </remarks> public override bool Equals( object obj ) { *************** *** 121,127 **** return false; } ! //Step 3: Check each important field // these 2 fields will not be null so compare them... if( this.SqlType.Equals( rhs.SqlType ) == false || this.Name.Equals( rhs.Name ) == false ) --- 167,202 ---- return false; } ! //Step 3: Check each important field + // verify the Parameter is actually a Parameter, and not a ParameterLength + // or ParameterPrecisionScale - this ensures that rhs.Equals(lhs) and + // lhs.Equals(rhs) always returns the same result. + return this.Equals( rhs, true ); + } + + /// <summary> + /// Determines if this instance and the specified object have the + /// same values. If <c>isTypeSensitive==true</c> then <c>rhs</c> + /// has to be a <see cref="Parameter"/> and can not be a subclass. + /// </summary> + /// <param name="rhs">The <see cref="Parameter"/> to compare to this instance.</param> + /// <param name="isTypeSensitive"> + /// <c>true</c> if <c>rhs</c> has to be a <see cref="Parameter"/> and not a subclass, + /// <c>false</c> if <c>rhs</c> can be a subclass of <see cref="Parameter"/>.</param> + /// <returns> + /// <c>true</c> if the properties in <see cref="Parameter"/> are all the same. + /// </returns> + protected bool Equals(Parameter rhs, bool isTypeSensitive) + { + if( isTypeSensitive ) + { + if( typeof(Parameter)!=rhs.GetType() ) + { + return false; + } + } + + // these 2 fields will not be null so compare them... if( this.SqlType.Equals( rhs.SqlType ) == false || this.Name.Equals( rhs.Name ) == false ) *************** *** 146,152 **** /// <summary> ! /// /// </summary> ! /// <returns></returns> public override int GetHashCode() { --- 221,229 ---- /// <summary> ! /// Gets a hash code based on the SqlType, Name, and TableAlias properties. /// </summary> ! /// <returns> ! /// An <see cref="Int32"/> value for the hash code. ! /// </returns> public override int GetHashCode() { *************** *** 159,169 **** hashCode += _sqlType.GetHashCode(); } ! if( name != null ) { ! hashCode += name.GetHashCode(); } ! if( tableAlias != null ) { ! hashCode += tableAlias.GetHashCode(); } --- 236,246 ---- hashCode += _sqlType.GetHashCode(); } ! if( _name != null ) { ! hashCode += _name.GetHashCode(); } ! if( _tableAlias != null ) { ! hashCode += _tableAlias.GetHashCode(); } *************** *** 175,179 **** public override string ToString() { ! return ( tableAlias == null || tableAlias.Length == 0 ) ? ":" + name : ":" + tableAlias + "." + name; } --- 252,256 ---- public override string ToString() { ! return ( _tableAlias == null || _tableAlias.Length == 0 ) ? ":" + _name : ":" + _tableAlias + "." + _name; } Index: SqlString.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/SqlString.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** SqlString.cs 31 Dec 2004 22:25:44 -0000 1.17 --- SqlString.cs 30 Jan 2005 19:39:13 -0000 1.18 *************** *** 36,39 **** --- 36,46 ---- /// <summary></summary> + /// <remarks> + /// TODO: modify this from object[] to an ICollection so that we can + /// safely say that SqlString truly is immutable. Right now someone + /// can change the contents of the array - hence changing the SqlString + /// and throwing any place this is used as a key in a hashtable into + /// an unfindable instance. + /// </remarks> public object[ ] SqlParts { *************** *** 211,215 **** /// <summary> ! /// Gets the indexes of the Parameters in the SqlParts /// </summary> /// <value> --- 218,222 ---- /// <summary> ! /// Gets the indexes of the Parameters in the SqlParts array. /// </summary> /// <value> *************** *** 408,411 **** --- 415,428 ---- //Step 3: Check each important field + + // if they don't contain the same number of parts then we + // can exit early because they are different + if( sqlParts.Length!=rhs.SqlParts.Length ) + { + return false; + } + + // they have the same number of parts - so compare each + // part for equallity. for( int i = 0; i < sqlParts.Length; i++ ) { *************** *** 416,419 **** --- 433,437 ---- } + // nothing has been found that is different - so they are equal. return true; } Index: QuerySelect.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/QuerySelect.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** QuerySelect.cs 23 Jan 2005 15:48:00 -0000 1.5 --- QuerySelect.cs 30 Jan 2005 19:39:13 -0000 1.6 *************** *** 353,358 **** if( token.Equals( StringHelper.SqlParameter ) ) { ! Parameter param = new Parameter(); ! param.Name = "placholder"; builder.Add( param ); } --- 353,357 ---- if( token.Equals( StringHelper.SqlParameter ) ) { ! Parameter param = new Parameter( "placeholder" ); builder.Add( param ); } Index: ParameterLength.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/ParameterLength.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** ParameterLength.cs 31 Dec 2004 22:25:19 -0000 1.8 --- ParameterLength.cs 30 Jan 2005 19:39:13 -0000 1.9 *************** *** 1,3 **** --- 1,4 ---- using System; + using NHibernate.SqlTypes; namespace NHibernate.SqlCommand *************** *** 13,25 **** /// </remarks> [Serializable] ! public class ParameterLength : Parameter { ! private int length; ! /// <summary></summary> public int Length { ! get { return length; } ! set { length = value; } } --- 14,56 ---- /// </remarks> [Serializable] ! public sealed class ParameterLength : Parameter { ! private int _length; ! /// <summary> ! /// Initializes a new instance of <see cref="ParameterLength"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="sqlType"> ! /// The <see cref="SqlType"/> that contains a Length ! /// to create the parameter for. ! /// </param> ! public ParameterLength(string name, SqlType sqlType) ! : this( name, null, sqlType ) ! { ! } ! ! /// <summary> ! /// Initializes a new instance of <see cref="ParameterLength"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="tableAlias">The Alias to use for the table.</param> ! /// <param name="sqlType"> ! /// The <see cref="SqlType"/> that contains a Length ! /// to create the parameter for. ! /// </param> ! public ParameterLength(string name, string tableAlias, SqlType sqlType) ! : base( name, tableAlias, sqlType ) ! { ! _length = sqlType.Length; ! } ! ! /// <summary> ! /// Gets the length of data the IDbDataParameter should hold. ! /// </summary> ! /// <value>The length of data the IDbDataParameter should hold.</value> public int Length { ! get { return _length; } } *************** *** 27,63 **** /// <summary> ! /// /// </summary> ! /// <param name="obj"></param> ! /// <returns></returns> public override bool Equals( object obj ) { ! if( base.Equals( obj ) ) ! { ! ParameterLength rhs; ! // Step 2: Instance of check ! rhs = obj as ParameterLength; ! if( rhs == null ) ! { ! return false; ! } ! //Step 3: Check each important field ! return this.Length.Equals( rhs.Length ); } ! else { return false; } } ! /// <summary></summary> public override int GetHashCode() { ! unchecked ! { ! return base.GetHashCode() + length.GetHashCode(); ! } } --- 58,115 ---- /// <summary> ! /// Determines wether this instance and the specified object ! /// are the same Type and have the same values. /// </summary> ! /// <param name="obj">An object to compare to this instance.</param> ! /// <returns> ! /// <c>true</c> if the object is a <see cref="ParameterLength" /> and has the ! /// same values. ! /// </returns> public override bool Equals( object obj ) { ! ParameterLength rhs = null; ! // Step1: Perform an equals test ! if( obj == this ) ! { ! return true; ! } ! // Step 2: Instance of check - don't need to worry about subclasses ! // getting in here because this class is sealed. ! rhs = obj as ParameterLength; ! if( rhs == null ) ! { ! return false; } ! ! //Step 3: Check each important field ! ! // isTypeSensitive is false because we want to check the values ! // of the fields - we know the rhs is a subclass of Parameter. ! if( this.Equals( rhs, false )==false ) { return false; } + + + return this.Length==rhs.Length; } ! /// <summary> ! /// Gets a hash code based on the SqlType, Name, and TableAlias properties. ! /// </summary> ! /// <returns> ! /// An <see cref="Int32"/> value for the hash code. ! /// </returns> ! /// <remarks> ! /// This just uses the <see cref="Parameter"/>'s <c>GetHashCode()</c> method. The ! /// compiler complains if Equals is implemented without a GetHashCode. ! /// </remarks> public override int GetHashCode() { ! // base should be sufficient enough because SqlType uses the ! // precision and scale to get the hash code ! return base.GetHashCode(); } Index: ParameterPrecisionScale.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/ParameterPrecisionScale.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** ParameterPrecisionScale.cs 31 Dec 2004 22:25:19 -0000 1.8 --- ParameterPrecisionScale.cs 30 Jan 2005 19:39:13 -0000 1.9 *************** *** 1,9 **** using System; namespace NHibernate.SqlCommand { /// <summary> ! /// Extension to the Parameter class that supports Parameters with ! /// a Precision and a Scale /// </summary> /// <remarks> --- 1,9 ---- using System; + using NHibernate.SqlTypes; namespace NHibernate.SqlCommand { /// <summary> ! /// An immutable Parameter that supports a Precision and a Scale /// </summary> /// <remarks> *************** *** 13,33 **** /// </remarks> [Serializable] ! public class ParameterPrecisionScale : Parameter { ! private byte precision; ! private byte scale; ! /// <summary></summary> public byte Precision { ! get { return precision; } ! set { precision = value; } } ! /// <summary></summary> public byte Scale { ! get { return scale; } ! set { scale = value; } } --- 13,66 ---- /// </remarks> [Serializable] ! public sealed class ParameterPrecisionScale : Parameter { ! private byte _precision; ! private byte _scale; ! ! /// <summary> ! /// Initializes a new instance of <see cref="ParameterPrecisionScale"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="sqlType"> ! /// The <see cref="SqlType"/> that contains a Precision & Scale ! /// to create the parameter for. ! /// </param> ! public ParameterPrecisionScale(string name, SqlType sqlType) ! : this( name, null, sqlType ) ! { ! } ! /// <summary> ! /// Initializes a new instance of <see cref="ParameterPrecisionScale"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="tableAlias">The Alias to use for the table.</param> ! /// <param name="sqlType"> ! /// The <see cref="SqlType"/> that contains a Precision & Scale ! /// to create the parameter for. ! /// </param> ! public ParameterPrecisionScale(string name, string tableAlias, SqlType sqlType ) ! : base( name, tableAlias, sqlType ) ! { ! _precision = sqlType.Precision; ! _scale = sqlType.Scale; ! } ! ! /// <summary> ! /// Gets the precision of data the IDbDataParameter should hold. ! /// </summary> ! /// <value>The precision of data the IDbDataParameter should hold.</value> public byte Precision { ! get { return _precision; } } ! /// <summary> ! /// Gets the scale of data the IDbDataParameter should hold. ! /// </summary> ! /// <value>The scale of data the IDbDataParameter should hold.</value> public byte Scale { ! get { return _scale; } } *************** *** 35,72 **** /// <summary> ! /// /// </summary> ! /// <param name="obj"></param> ! /// <returns></returns> public override bool Equals( object obj ) { ! if( base.Equals( obj ) ) ! { ! ParameterPrecisionScale rhs; ! // Step 2: Instance of check ! rhs = obj as ParameterPrecisionScale; ! if( rhs == null ) ! { ! return false; ! } ! //Step 3: Check each important field ! return this.Precision == rhs.Precision ! && this.Scale == rhs.Scale; } ! else { return false; } } ! /// <summary></summary> public override int GetHashCode() { ! unchecked ! { ! return base.GetHashCode() + precision.GetHashCode() + scale.GetHashCode(); ! } } --- 68,125 ---- /// <summary> ! /// Determines wether this instance and the specified object ! /// are the same Type and have the same values. /// </summary> ! /// <param name="obj">An object to compare to this instance.</param> ! /// <returns> ! /// <c>true</c> if the object is a <see cref="ParameterPrecisionScale" /> and has the ! /// same values. ! /// </returns> public override bool Equals( object obj ) { ! ParameterPrecisionScale rhs = null; ! // Step1: Perform an equals test ! if( obj == this ) ! { ! return true; ! } ! // Step 2: Instance of check - don't need to worry about subclasses ! // getting in here because this class is sealed. ! rhs = obj as ParameterPrecisionScale; ! if( rhs == null ) ! { ! return false; } ! ! //Step 3: Check each important field ! ! // isTypeSensitive is false because we want to check the values ! // of the fields - we know the rhs is a subclass of Parameter. ! if( this.Equals( rhs, false )==false ) { return false; } + + return this.Precision == rhs.Precision + && this.Scale == rhs.Scale; } ! /// <summary> ! /// Gets a hash code based on the SqlType, Name, and TableAlias properties. ! /// </summary> ! /// <returns> ! /// An <see cref="Int32"/> value for the hash code. ! /// </returns> ! /// <remarks> ! /// This just uses the <see cref="Parameter"/>'s <c>GetHashCode()</c> method. The ! /// compiler complains if Equals is implemented without a GetHashCode. ! /// </remarks> public override int GetHashCode() { ! // base should be sufficient enough because SqlType factors ! // in the Precision and Scale to the hash code. ! return base.GetHashCode(); } |