merge -r 60439:60440
[mono.git] / mcs / class / System.Data / Mono.Data.SqlExpressions / Like.cs
1 //
2 // Like.cs
3 //
4 // Author:
5 //   Juraj Skripsky (juraj@hotfeet.ch)
6 //
7 // (C) 2004 HotFeet GmbH (http://www.hotfeet.ch)
8 //
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Collections;
35 using System.Data;
36
37 namespace Mono.Data.SqlExpressions {
38         internal class Like : UnaryExpression {
39                 string pattern;
40                 bool openStart, openEnd;
41                 
42                 public Like (IExpression e, string pattern) : base (e)
43                 {
44                         string original = pattern;
45                         int len = pattern.Length;
46                         openStart = (pattern[0] == '*' || pattern[0] == '%');
47                         openEnd = (pattern[len - 1] == '*' || pattern[len - 1] == '%');
48                         
49                         pattern = pattern.Trim ('*', '%');
50                         pattern = pattern.Replace ("[*]", "[[0]]");
51                         pattern = pattern.Replace ("[%]", "[[1]]");
52                         if (pattern.IndexOf('*') != -1 || pattern.IndexOf('%') != -1)
53                                 throw new EvaluateException (String.Format ("Pattern '{0}' is invalid.", original));
54                         pattern = pattern.Replace ("[[0]]", "*");
55                         pattern = pattern.Replace ("[[1]]", "%");
56                         pattern = pattern.Replace ("[[]", "[");
57                         pattern = pattern.Replace ("[]]", "]");
58                         this.pattern = pattern;
59                 }
60
61                 public override bool Equals(object obj)
62                 {
63                         if (!base.Equals (obj))
64                                 return false;
65
66                         if (!(obj is Like))
67                                 return false;
68
69                         Like other = (Like) obj;
70                         if (other.pattern != pattern)
71                                 return false;
72
73                         return true;
74                 }
75
76                 public override int GetHashCode()
77                 {
78                         return pattern.GetHashCode () ^ base.GetHashCode ();
79                 }
80
81                 override public object Eval (DataRow row)
82                 {
83                         object o = expr.Eval (row);
84                         if (o == DBNull.Value)
85                                 return o;
86                         string str = (string)o;
87                         string pattern = this.pattern;
88                         if (!row.Table.CaseSensitive) {
89                                 str = str.ToLower();
90                                 pattern = pattern.ToLower();
91                         }
92                         
93                         int idx = str.IndexOf (pattern);
94                         if (idx == -1)
95                                 return false;
96                                 
97                         return (idx == 0 || openStart) && (idx + pattern.Length == str.Length || openEnd);
98                 }
99         }
100 }