Clover.NET coverage report - Coverage for s2dao.net

Coverage timestamp: 2006年5月18日 15:09:15

File Stats: LOC: 252   Methods: 20
NCLOC: 213 Classes: 1
 
Source File Conditionals Statements Methods TOTAL
Seasar.Dao.Parser\SqlParserImpl.cs 91.2% 96.5% 100.0% 95.7%
coverage coverage
1   #region Copyright
2   /*
3   * Copyright 2005 the Seasar Foundation and the Others.
4   *
5   * Licensed under the Apache License, Version 2.0 (the "License");
6   * you may not use this file except in compliance with the License.
7   * You may obtain a copy of the License at
8   *
9   * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
14   * either express or implied. See the License for the specific language
15   * governing permissions and limitations under the License.
16   */
17   #endregion
18  
19   using System;
20   using System.Collections;
21   using Seasar.Dao.Node;
22   using Seasar.Framework.Util;
23  
24   namespace Seasar.Dao.Parser
25   {
26   public class SqlParserImpl : ISqlParser
27   {
28   private ISqlTokenizer tokenizer;
29   private Stack nodeStack = new Stack();
30  
31 73 public SqlParserImpl(string sql)
32   {
33 73 sql = sql.Trim();
34 73 if (sql.EndsWith(";"))
35   {
36 3 sql = sql.Substring(0, sql.Length - 1);
37   }
38 73 tokenizer = new SqlTokenizerImpl(sql);
39   }
40  
41 73 public INode Parse()
42   {
43 73 Push(new ContainerNode());
44 262 while (TokenType.EOF != tokenizer.Next())
45   {
46 191 ParseToken();
47   }
48 71 return Pop();
49   }
50  
51 229 protected void ParseToken()
52   {
53 229 switch (tokenizer.TokenType)
54   {
55   case TokenType.SQL:
56 129 ParseSql();
57 129 break;
58   case TokenType.COMMENT:
59 79 ParseComment();
60 78 break;
61   case TokenType.ELSE:
62 5 ParseElse();
63 5 break;
64   case TokenType.BIND_VARIABLE:
65 16 ParseBindVariable();
66 16 break;
67   }
68   }
69  
70 129 protected void ParseSql()
71   {
72 129 string sql = tokenizer.Token;
73 129 if (IsElseMode())
74   {
75 6 sql = sql.Replace("--", "");
76   }
77 129 INode node = Peek();
78  
79 129 if ( (node is IfNode || node is ElseNode) && node.ChildSize == 0)
80   {
81 16 ISqlTokenizer st = new SqlTokenizerImpl(sql);
82 16 st.SkipWhitespace();
83 16 string token = st.SkipToken();
84 16 st.SkipWhitespace();
85 16 if ("AND".Equals(token.ToUpper()) || "OR".Equals(token.ToUpper()))
86   {
87 2 node.AddChild(new PrefixSqlNode(st.Before, st.After));
88   }
89   else
90   {
91 14 node.AddChild(new SqlNode(sql));
92   }
93   }
94   else
95   {
96 113 node.AddChild(new SqlNode(sql));
97   }
98   }
99  
100 79 protected void ParseComment()
101   {
102 79 string comment = tokenizer.Token;
103 79 if (IsTargetComment(comment))
104   {
105 78 if (IsIfComment(comment))
106   {
107 11 ParseIf();
108   }
109 67 else if (IsBeginComment(comment))
110   {
111 4 ParseBegin();
112   }
113 63 else if (IsEndComment(comment))
114   {
115 0 return;
116   }
117   else
118   {
119 63 ParseCommentBindVariable();
120   }
121   }
122   }
123  
124 11 protected void ParseIf()
125   {
126 11 string condition = tokenizer.Token.Substring(2).Trim();
127 11 if (StringUtil.IsEmpty(condition))
128   {
129 0 throw new IfConditionNotFoundRuntimeException();
130   }
131 11 IfNode ifNode = new IfNode(condition);
132 11 Peek().AddChild(ifNode);
133 11 Push(ifNode);
134 11 ParseEnd();
135   }
136  
137 4 protected void ParseBegin()
138   {
139 4 BeginNode beginNode = new BeginNode();
140 4 Peek().AddChild(beginNode);
141 4 Push(beginNode);
142 4 ParseEnd();
143   }
144  
145 15 protected void ParseEnd()
146   {
147 53 while (TokenType.EOF != tokenizer.Next())
148   {
149 52 if (tokenizer.TokenType == TokenType.COMMENT
150   && IsEndComment(tokenizer.Token))
151   {
152 14 Pop();
153 14 return;
154   }
155 38 ParseToken();
156   }
157 1 throw new EndCommentNotFoundRuntimeException();
158   }
159  
160 5 protected void ParseElse()
161   {
162 5 INode parent = Peek();
163 5 if ( !(parent is IfNode) )
164   {
165 0 return;
166   }
167 5 IfNode ifNode = (IfNode) Pop();
168 5 ElseNode elseNode = new ElseNode();
169 5 ifNode.ElseNode = elseNode;
170 5 Push(elseNode);
171 5 tokenizer.SkipWhitespace();
172   }
173  
174 63 protected void ParseCommentBindVariable()
175   {
176 63 string expr = tokenizer.Token;
177 63 string s = tokenizer.SkipToken();
178 63 if (s.StartsWith("(") && s.EndsWith(")"))
179   {
180 18 Peek().AddChild(new ParenBindVariableNode(expr));
181   }
182 45 else if (expr.StartsWith("$"))
183   {
184 1 Peek().AddChild(new EmbeddedValueNode(expr.Substring(1)));
185   }
186   else
187   {
188 44 Peek().AddChild(new BindVariableNode(expr));
189   }
190   }
191  
192 16 protected void ParseBindVariable()
193   {
194 16 string expr = tokenizer.Token;
195 16 Peek().AddChild(new BindVariableNode(expr));
196   }
197  
198 90 protected INode Pop()
199   {
200 90 return (INode) nodeStack.Pop();
201   }
202  
203 228 protected INode Peek()
204   {
205 228 return (INode) nodeStack.Peek();
206   }
207  
208 93 protected void Push(INode node)
209   {
210 93 nodeStack.Push(node);
211   }
212  
213 129 protected bool IsElseMode()
214   {
215 273 for (int i = 0; i < nodeStack.Count; ++i)
216   {
217 150 if (nodeStack.ToArray()[i] is ElseNode)
218   {
219 6 return true;
220   }
221   }
222 123 return false;
223   }
224  
225 79 private static bool IsTargetComment(string comment)
226   {
227 79 return comment != null && comment.Length > 0
228   && IsCSharpIdentifierStart(comment.ToCharArray()[0]);
229   }
230  
231 79 private static bool IsCSharpIdentifierStart(Char c)
232   {
233 79 return Char.IsLetterOrDigit(c) || c == '_' || c == '\\' || c == '$' || c == '@';
234   }
235  
236 78 private static bool IsIfComment(string comment)
237   {
238 78 return comment.StartsWith("IF");
239   }
240  
241 67 private static bool IsBeginComment(string content)
242   {
243 67 return content != null && "BEGIN".Equals(content);
244   }
245  
246 90 private static bool IsEndComment(string content)
247   {
248 90 return content != null && "END".Equals(content);
249   }
250   }
251   }
252