Add licensing info
[mono.git] / mcs / class / Mono.Data.PostgreSqlClient / Mono.Data.PostgreSqlClient / ParmUtil.cs
1 //\r
2 // ParmUtil.cs - utility to bind variables in a SQL statement to parameters in C# code\r
3 //               This is in the PostgreSQL .NET Data provider in Mono\r
4 //\r
5 // Author: \r
6 //    Daniel Morgan <danmorg@sc.rr.com>\r
7 //\r
8 // (c)copyright 2002 Daniel Morgan\r
9 //\r
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 \r
32 // comment DEBUG_ParmUtil for production, for debug messages, uncomment\r
33 //#define DEBUG_ParmUtil\r
34 \r
35 using System;\r
36 using System.Data;\r
37 using System.Text;\r
38 \r
39 namespace Mono.Data.PostgreSqlClient {\r
40 \r
41         enum PostgresBindVariableCharacter {\r
42                 Semicolon,\r
43                 At,\r
44                 QuestionMark\r
45         }\r
46 \r
47         public class ParmUtil {\r
48 \r
49                 private string sql = "";\r
50                 private string resultSql = "";\r
51                 private PgSqlParameterCollection parmsCollection = null;\r
52                 \r
53                 static private PostgresBindVariableCharacter PgbindChar = PostgresBindVariableCharacter.Semicolon;\r
54                 static char bindChar;\r
55 \r
56                 // static constructor\r
57                 static ParmUtil() {\r
58                         switch(PgbindChar) {\r
59                         case PostgresBindVariableCharacter.Semicolon:\r
60                                 bindChar = ':';\r
61                                 break;\r
62                         case PostgresBindVariableCharacter.At:\r
63                                 bindChar = '@';\r
64                                 break;\r
65                         case PostgresBindVariableCharacter.QuestionMark:\r
66                                 // this doesn't have named parameters,\r
67                                 // they must be in order\r
68                                 bindChar = '?';\r
69                                 break;\r
70                         }\r
71                 }\r
72                                 \r
73                 public ParmUtil(string query, PgSqlParameterCollection parms) {\r
74                         sql = query;\r
75                         parmsCollection = parms;\r
76                 }\r
77                 \r
78                 public string ResultSql {\r
79                         get {\r
80                                 return resultSql;\r
81                         }\r
82                 }\r
83 \r
84                 // TODO: currently only works for input variables,\r
85                 //       need to do input/output, output, and return\r
86                 public string ReplaceWithParms() {\r
87 \r
88                         StringBuilder result = new StringBuilder();\r
89                         char[] chars = sql.ToCharArray();\r
90                         bool bStringConstFound = false;\r
91 \r
92                         for(int i = 0; i < chars.Length; i++) {\r
93                                 if(chars[i] == '\'') {\r
94                                         if(bStringConstFound == true)\r
95                                                 bStringConstFound = false;\r
96                                         else\r
97                                                 bStringConstFound = true;\r
98 \r
99                                         result.Append(chars[i]);\r
100                                 }\r
101                                 else if(chars[i] == bindChar && \r
102                                         bStringConstFound == false) {\r
103 #if DEBUG_ParmUtil\r
104                                         Console.WriteLine("Bind Variable character found...");\r
105 #endif                                  \r
106                                         StringBuilder parm = new StringBuilder();\r
107                                         i++;\r
108                                         while(i <= chars.Length) {\r
109                                                 char ch;\r
110                                                 if(i == chars.Length)\r
111                                                         ch = ' '; // a space\r
112                                                 else\r
113                                                         ch = chars[i];\r
114 \r
115 #if DEBUG_ParmUtil                                              \r
116                                                 Console.WriteLine("Is char Letter or digit?");\r
117 #endif                                          \r
118                                                 if(Char.IsLetterOrDigit(ch)) {\r
119 #if DEBUG_ParmUtil\r
120                                                         Console.WriteLine("Char IS letter or digit. " + \r
121                                                                 "Now, append char to parm StringBuilder");\r
122 #endif\r
123                                                         parm.Append(ch);\r
124                                                 }\r
125                                                 else {\r
126 #if DEBUG_ParmUtil\r
127                                                         Console.WriteLine("Char is NOT letter or char. " + \r
128                                                                 "thus we got rest of bind variable name. ");\r
129                                                                 \r
130                                                         // replace bind variable placeholder \r
131                                                         // with data value constant\r
132                                                         Console.WriteLine("parm StringBuilder to string p...");\r
133 #endif\r
134                                                         string p = parm.ToString();\r
135 #if DEBUG_ParmUtil\r
136                                                         Console.WriteLine("calling BindReplace...");\r
137 #endif                                                  \r
138                                                         bool found = BindReplace(result, p);\r
139 #if DEBUG_ParmUtil\r
140                                                         Console.WriteLine("    Found = " + found);\r
141 #endif\r
142                                                         if(found == true)\r
143                                                                 break;\r
144                                                         else {                                          \r
145                                                                 // *** Error Handling\r
146                                                                 Console.WriteLine("Error: parameter not found: " + p);\r
147                                                                 return "";\r
148                                                         }\r
149                                                 }\r
150                                                 i++;\r
151                                         }\r
152                                         i--;\r
153                                 }\r
154                                 else \r
155                                         result.Append(chars[i]);\r
156                         }\r
157                         \r
158                         resultSql = result.ToString();\r
159                         return resultSql;\r
160                 }\r
161 \r
162                 public bool BindReplace (StringBuilder result, string p) {\r
163                         // bind variable\r
164                         bool found = false;\r
165 \r
166 #if DEBUG_ParmUtil\r
167                         Console.WriteLine("Does the parmsCollection contain the parameter???: " + p);\r
168 #endif\r
169                         if(parmsCollection.Contains(p) == true) {\r
170                                 // parameter found\r
171 #if DEBUG_ParmUtil\r
172                                 Console.WriteLine("Parameter Found: " + p);\r
173 #endif\r
174                                 PgSqlParameter prm = parmsCollection[p];\r
175 \r
176 #if DEBUG_ParmUtil                                                                                                                                      \r
177                                 // DEBUG \r
178                                 Console.WriteLine("          Value: " + prm.Value);\r
179                                 Console.WriteLine("      Direction: " + prm.Direction);\r
180 #endif\r
181                                 // convert object to string and place\r
182                                 // into SQL\r
183                                 if(prm.Direction == ParameterDirection.Input) {\r
184                                         string strObj = PostgresHelper.\r
185                                                 ObjectToString(prm.DbType, \r
186                                                                 prm.Value);\r
187                                         result.Append(strObj);\r
188                                 }\r
189                                 else\r
190                                         result.Append(bindChar + p);\r
191 \r
192                                 found = true;\r
193                         }\r
194                         return found;\r
195                 }\r
196         }\r
197 }\r