Clover.NET coverage report - Coverage for s2dao.net

Coverage timestamp: 2006年5月30日 11:48:56

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 110 public SqlParserImpl(string sql)
32   {
33 110 sql = sql.Trim();
34 110 if (sql.EndsWith(";"))
35   {
36 3 sql = sql.Substring(0, sql.Length - 1);
37   }
38 110 tokenizer = new SqlTokenizerImpl(sql);
39   }
40  
41 110 public INode Parse()
42   {
43 110 Push(new ContainerNode());
44 383 while (TokenType.EOF != tokenizer.Next())
45   {
46 275 ParseToken();
47   }
48 108 return Pop();
49   }
50  
51 371 protected void ParseToken()
52   {
53 371 switch (tokenizer.TokenType)
54   {
55   case TokenType.SQL:
56 210 ParseSql();
57 210 break;
58   case TokenType.COMMENT:
59 140 ParseComment();
60 139 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 210 protected void ParseSql()
71   {
72 210 string sql = tokenizer.Token;
73 210 if (IsElseMode())
74   {
75 6 sql = sql.Replace("--", "");
76   }
77 210 INode node = Peek();
78  
79 210 if ( (node is IfNode || node is ElseNode) && node.ChildSize == 0)
80   {
81 34 ISqlTokenizer st = new SqlTokenizerImpl(sql);
82 34 st.SkipWhitespace();
83 34 string token = st.SkipToken();
84 34 st.SkipWhitespace();
85 34 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 32 node.AddChild(new SqlNode(sql));
92   }
93   }
94   else
95   {
96 176 node.AddChild(new SqlNode(sql));
97   }
98   }
99  
100 140 protected void ParseComment()
101   {
102 140 string comment = tokenizer.Token;
103 140 if (IsTargetComment(comment))
104   {
105 139 if (IsIfComment(comment))
106   {
107 29 ParseIf();
108   }
109 110 else if (IsBeginComment(comment))
110   {
111 8 ParseBegin();
112   }
113 102 else if (IsEndComment(comment))
114   {
115 0 return;
116   }
117   else
118   {
119 102 ParseCommentBindVariable();
120   }
121   }
122   }
123  
124 29 protected void ParseIf()
125   {
126 29 string condition = tokenizer.Token.Substring(2).Trim();
127 29 if (StringUtil.IsEmpty(condition))
128   {
129 0 throw new IfConditionNotFoundRuntimeException();
130   }
131 29 IfNode ifNode = new IfNode(condition);
132 29 Peek().AddChild(ifNode);
133 29 Push(ifNode);
134 29 ParseEnd();
135   }
136  
137 8 protected void ParseBegin()
138   {
139 8 BeginNode beginNode = new BeginNode();
140 8 Peek().AddChild(beginNode);
141 8 Push(beginNode);
142 8 ParseEnd();
143   }
144  
145 37 protected void ParseEnd()
146   {
147 133 while (TokenType.EOF != tokenizer.Next())
148   {
149 132 if (tokenizer.TokenType == TokenType.COMMENT
150   && IsEndComment(tokenizer.Token))
151   {
152 36 Pop();
153 36 return;
154   }
155 96 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 102 protected void ParseCommentBindVariable()
175   {
176 102 string expr = tokenizer.Token;
177 102 string s = tokenizer.SkipToken();
178 102 if (s.StartsWith("(") && s.EndsWith(")"))
179   {
180 18 Peek().AddChild(new ParenBindVariableNode(expr));
181   }
182 84 else if (expr.StartsWith("$"))
183   {
184 1 Peek().AddChild(new EmbeddedValueNode(expr.Substring(1)));
185   }
186   else
187   {
188 83 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 149 protected INode Pop()
199   {
200 149 return (INode) nodeStack.Pop();
201   }
202  
203 370 protected INode Peek()
204   {
205 370 return (INode) nodeStack.Peek();
206   }
207  
208 152 protected void Push(INode node)
209   {
210 152 nodeStack.Push(node);
211   }
212  
213 210 protected bool IsElseMode()
214   {
215 475 for (int i = 0; i < nodeStack.Count; ++i)
216   {
217 271 if (nodeStack.ToArray()[i] is ElseNode)
218   {
219 6 return true;
220   }
221   }
222 204 return false;
223   }
224  
225 140 private static bool IsTargetComment(string comment)
226   {
227 140 return comment != null && comment.Length > 0
228   && IsCSharpIdentifierStart(comment.ToCharArray()[0]);
229   }
230  
231 140 private static bool IsCSharpIdentifierStart(Char c)
232   {
233 140 return Char.IsLetterOrDigit(c) || c == '_' || c == '\\' || c == '$' || c == '@';
234   }
235  
236 139 private static bool IsIfComment(string comment)
237   {
238 139 return comment.StartsWith("IF");
239   }
240  
241 110 private static bool IsBeginComment(string content)
242   {
243 110 return content != null && "BEGIN".Equals(content);
244   }
245  
246 173 private static bool IsEndComment(string content)
247   {
248 173 return content != null && "END".Equals(content);
249   }
250   }
251   }
252