Skip to content

Commit

Permalink
Introduce MongoRegexOption which allows to simply set the option with…
Browse files Browse the repository at this point in the history
…out knowing the correct char. It dose noting more then changing the RawOptions so future server extensions are still possible with it.
  • Loading branch information
lanwin committed Jun 1, 2010
1 parent 7f32fb7 commit 45cd3a7
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 73 deletions.
40 changes: 37 additions & 3 deletions source/MongoDB.Tests/UnitTests/TestMongoRegex.cs
Expand Up @@ -9,19 +9,53 @@ namespace MongoDB.UnitTests
public class TestMongoRegex
{
[Test]
public void CanBeCunstructedFromNullExceptionAndOptions()
public void CanBeCunstructedFromNullExpressionAndOptions()
{
var regex = new MongoRegex(null, null);
Assert.IsNull(regex.Expression);
Assert.IsNull(regex.Options);
Assert.IsNull(regex.RawOptions);
}

[Test]
public void CanBeConstructed()
{
var regex = new MongoRegex("expression");
Assert.AreEqual("expression", regex.Expression);
Assert.AreEqual(string.Empty, regex.RawOptions);
}

[Test]
public void CanBeConstructedWithOption()
{
var regex = new MongoRegex("expression", "options");
Assert.AreEqual("expression",regex.Expression);
Assert.AreEqual("options",regex.Options);
Assert.AreEqual("options",regex.RawOptions);
}

[Test]
public void CanBeConstructedWithMongoRegexOption()
{
var regex = new MongoRegex("expression", MongoRegexOption.IgnoreCase | MongoRegexOption.IgnorePatternWhitespace | MongoRegexOption.Multiline);
Assert.AreEqual("expression", regex.Expression);
Assert.AreEqual("img", regex.RawOptions);
}

[Test]
public void CanReadOptions()
{
var regex = new MongoRegex("expression", "img");
Assert.AreEqual(MongoRegexOption.IgnoreCase | MongoRegexOption.IgnorePatternWhitespace | MongoRegexOption.Multiline, regex.Options);
}

[Test]
public void CanSetOptions()
{
var regex = new MongoRegex("expression", null)
{
Options = MongoRegexOption.IgnoreCase & MongoRegexOption.IgnorePatternWhitespace
};

Assert.AreEqual("ig",regex.RawOptions);
}

[Test]
Expand Down
2 changes: 1 addition & 1 deletion source/MongoDB/Bson/BsonReader.cs
Expand Up @@ -321,7 +321,7 @@ public BsonReader(Stream stream, BsonReaderSettings settings)
private object ReadRegex(){
return new MongoRegex{
Expression = ReadString(),
Options = ReadString()
RawOptions = ReadString()
};
}

Expand Down
4 changes: 2 additions & 2 deletions source/MongoDB/Bson/BsonWriter.cs
Expand Up @@ -200,7 +200,7 @@ private void Write(Code code)
private void Write(MongoRegex regex)
{
Write(regex.Expression, false);
Write(regex.Options, false);
Write(regex.RawOptions, false);
}

/// <summary>
Expand Down Expand Up @@ -383,7 +383,7 @@ private int CalculateSize(Code code)
public int CalculateSize(MongoRegex regex)
{
var size = CalculateSize(regex.Expression, false);
size += CalculateSize(regex.Options, false);
size += CalculateSize(regex.RawOptions, false);
return size;
}

Expand Down
1 change: 1 addition & 0 deletions source/MongoDB/MongoDB.csproj
Expand Up @@ -138,6 +138,7 @@
<Compile Include="Linq\Translators\ExpressionReplacer.cs" />
<Compile Include="MapReduce.cs" />
<Compile Include="Commands\MapReduceCommand.cs" />
<Compile Include="MongoRegexOption.cs" />
<Compile Include="Results\MapReduceResult.cs" />
<Compile Include="Serialization\Builders\DictionaryBuilder.cs" />
<Compile Include="Serialization\Builders\PropertyDescriptor.cs" />
Expand Down
199 changes: 132 additions & 67 deletions source/MongoDB/MongoRegex.cs
Expand Up @@ -26,6 +26,17 @@ public MongoRegex(string expression)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="MongoRegex"/> class.
/// </summary>
/// <param name="expression">The expression.</param>
/// <param name="options">The options.</param>
public MongoRegex(string expression,MongoRegexOption options)
{
Expression = expression;
Options = options;
}

/// <summary>
/// Initializes a new instance of the <see cref = "MongoRegex" /> class.
/// </summary>
Expand All @@ -34,20 +45,131 @@ public MongoRegex(string expression)
public MongoRegex(string expression, string options)
{
Expression = expression;
Options = options;
RawOptions = options;
}

/// <summary>
/// A valid regex string including the enclosing / characters.
/// </summary>
public string Expression { get; set; }

/// <summary>
/// Gets or sets the options.
/// </summary>
/// <value>The options.</value>
public MongoRegexOption Options
{
get
{
var options = MongoRegexOption.None;

if(RawOptions!=null)
{
if(RawOptions.Contains("i"))
options = options | MongoRegexOption.IgnoreCase;
if(RawOptions.Contains("m"))
options = options | MongoRegexOption.Multiline;
if(RawOptions.Contains("g"))
options = options | MongoRegexOption.IgnorePatternWhitespace;
}

return options;
}
set
{
ToggleOption("i", (value & MongoRegexOption.IgnoreCase) != 0);
ToggleOption("m", (value & MongoRegexOption.Multiline) != 0);
ToggleOption("g", (value & MongoRegexOption.IgnorePatternWhitespace) != 0);
}
}

/// <summary>
/// A string that may contain only the characters 'g', 'i', and 'm'.
/// Because the JS and TenGen representations support a limited range of options,
/// any nonconforming options will be dropped when converting to this representation
/// </summary>
public string Options { get; set; }
public string RawOptions { get; set; }

/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name = "other">An object to compare with this object.</param>
/// <returns>
/// true if the current object is equal to the <paramref name = "other" /> parameter; otherwise, false.
/// </returns>
public bool Equals(MongoRegex other)
{
if(ReferenceEquals(null, other))
return false;
if(ReferenceEquals(this, other))
return true;
return Equals(other.Expression, Expression) && Equals(other.RawOptions, RawOptions);
}

/// <summary>
/// This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should return null (Nothing in Visual Basic) from this method, and instead, if specifying a custom schema is required, apply the <see cref = "T:System.Xml.Serialization.XmlSchemaProviderAttribute" /> to the class.
/// </summary>
/// <returns>
/// An <see cref = "T:System.Xml.Schema.XmlSchema" /> that describes the XML representation of the object that is produced by the <see cref = "M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)" /> method and consumed by the <see cref = "M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)" /> method.
/// </returns>
XmlSchema IXmlSerializable.GetSchema()
{
return null;
}

/// <summary>
/// Generates an object from its XML representation.
/// </summary>
/// <param name = "reader">The <see cref = "T:System.Xml.XmlReader" /> stream from which the object is deserialized.</param>
void IXmlSerializable.ReadXml(XmlReader reader)
{
if(reader.MoveToAttribute("options"))
RawOptions = reader.Value;

if(reader.IsEmptyElement)
return;

Expression = reader.ReadString();
}

/// <summary>
/// Converts an object into its XML representation.
/// </summary>
/// <param name = "writer">The <see cref = "T:System.Xml.XmlWriter" /> stream to which the object is serialized.</param>
void IXmlSerializable.WriteXml(XmlWriter writer)
{
if(RawOptions != null)
writer.WriteAttributeString("options", RawOptions);

if(Expression == null)
return;

writer.WriteString(Expression);
}

/// <summary>
/// Toggles the option.
/// </summary>
/// <param name = "option">The option.</param>
/// <param name = "enabled">if set to <c>true</c> [enabled].</param>
private void ToggleOption(string option, bool enabled)
{
if(RawOptions == null)
RawOptions = string.Empty;

if(enabled)
{
if(RawOptions.Contains(option))
return;
RawOptions += option;
}
else
{
if(!RawOptions.Contains(option))
return;
RawOptions = RawOptions.Replace(option, string.Empty);
}
}

/// <summary>
/// Determines whether the specified <see cref = "System.Object" /> is equal to this instance.
Expand All @@ -69,37 +191,21 @@ public override bool Equals(object obj)
}

/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>
/// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
/// </returns>
public bool Equals(MongoRegex other)
{
if(ReferenceEquals(null, other))
return false;
if(ReferenceEquals(this, other))
return true;
return Equals(other.Expression, Expression) && Equals(other.Options, Options);
}

/// <summary>
/// Implements the operator ==.
/// Implements the operator ==.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <param name = "left">The left.</param>
/// <param name = "right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(MongoRegex left, MongoRegex right)
{
return Equals(left, right);
}

/// <summary>
/// Implements the operator !=.
/// Implements the operator !=.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <param name = "left">The left.</param>
/// <param name = "right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(MongoRegex left, MongoRegex right)
{
Expand All @@ -116,7 +222,7 @@ public override int GetHashCode()
{
unchecked
{
return ((Expression != null ? Expression.GetHashCode() : 0)*397) ^ (Options != null ? Options.GetHashCode() : 0);
return ((Expression != null ? Expression.GetHashCode() : 0)*397) ^ (RawOptions != null ? RawOptions.GetHashCode() : 0);
}
}

Expand All @@ -128,48 +234,7 @@ public override int GetHashCode()
/// </returns>
public override string ToString()
{
return string.Format("{0}{1}", Expression, Options);
}

/// <summary>
/// This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should return null (Nothing in Visual Basic) from this method, and instead, if specifying a custom schema is required, apply the <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"/> to the class.
/// </summary>
/// <returns>
/// An <see cref="T:System.Xml.Schema.XmlSchema"/> that describes the XML representation of the object that is produced by the <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"/> method and consumed by the <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"/> method.
/// </returns>
XmlSchema IXmlSerializable.GetSchema()
{
return null;
}

/// <summary>
/// Generates an object from its XML representation.
/// </summary>
/// <param name="reader">The <see cref="T:System.Xml.XmlReader"/> stream from which the object is deserialized.</param>
void IXmlSerializable.ReadXml(XmlReader reader)
{
if(reader.MoveToAttribute("options"))
Options = reader.Value;

if(reader.IsEmptyElement)
return;

Expression = reader.ReadString();
}

/// <summary>
/// Converts an object into its XML representation.
/// </summary>
/// <param name="writer">The <see cref="T:System.Xml.XmlWriter"/> stream to which the object is serialized.</param>
void IXmlSerializable.WriteXml(XmlWriter writer)
{
if(Options!=null)
writer.WriteAttributeString("options", Options);

if(Expression==null)
return;

writer.WriteString(Expression);
return string.Format("{0}{1}", Expression, RawOptions);
}
}
}
30 changes: 30 additions & 0 deletions source/MongoDB/MongoRegexOption.cs
@@ -0,0 +1,30 @@
using System;

namespace MongoDB
{
/// <summary>
/// Mongo Regex options
/// </summary>
[Flags]
public enum MongoRegexOption
{
/// <summary>
/// Specifies that no options are set.
/// </summary>
None = 0,
/// <summary>
/// i - Specifies case-insensitive matching.
/// </summary>
IgnoreCase = 1,
/// <summary>
/// m - Multiline mode. Changes the meaning of ^ and $ so they match at the beginning
/// and end, respectively, of any line, and not just the beginning and end of the
/// entire string.
/// </summary>
Multiline = 2,
/// <summary>
/// g - Eliminates unescaped white space from the pattern.
/// </summary>
IgnorePatternWhitespace = 3
}
}

0 comments on commit 45cd3a7

Please sign in to comment.