//======================================================================================== // ParseComplex() //======================================================================================== private void ParseComplex(ref int start, StatementCollection statements) { int i = start; int saveStart = start; int depth = 0; bool found = false; bool inString = false; char c = Char.MinValue; var token = new StringBuilder(); string word; while ((i < sql.Length) && !found) { c = sql[i]; if (inString) { if (c == '\'') { inString = false; } token.Append(c); } else if (c == ';') { if (depth < 0) { found = true; } else if (token.Length > 0) { word = token.ToString().ToUpper(); if (word.Equals("END")) { depth--; } if (depth < 0) { found = true; } } token.Length = 0; } else if (Char.IsWhiteSpace(c)) { word = token.ToString().ToUpper(); if (blockCmds.Contains(word)) { depth++; } else if (word.Equals("END")) { depth--; } token.Length = 0; } else { if (c == '\'') { inString = true; } token.Append(c); } i++; } var query = new StringBuilder(); if (found) { query.Append(sql.Substring(start, i - start)); if (query[query.Length - 1] != ';') { query.Append(';'); } start = i + 1; } else { query.Append(sql.Substring(start)); if (query[query.Length - 1] != ';') { query.Append(';'); } start = sql.Length; } if (isOptimized) { statements.Add(query.ToString()); } else { int a = (int)map[saveStart]; int b = (int)map[i - 1]; query.Length = 0; query.Append(text.Substring(a, b - a + 1)); if (query[query.Length - 1] != ';') { query.Append(';'); } statements.Add(query.ToString()); } }
//======================================================================================== // Parse() //======================================================================================== #region Parse private void Parse(int start, int delimIndex, StatementCollection statements) { if ((sql == null) || (sql.Length == 0) || (start >= sql.Length)) { return; } if (sql[start] == ' ') { start++; } // extract first keyword in query string word; int space = sql.IndexOf(' ', start); if (space < 0) { // found last word. now strip the final semicolon int end = sql.IndexOf(';', start); if (end < 0) { word = sql.Substring(start).Trim(); } else { word = sql.Substring(start, end - start).Trim(); } } else { word = sql.Substring(start, sql.IndexOf(' ', start) - start).ToUpper(); } // test extract keyword for important delimeters if (word.Equals("/")) { // ignore the / command Parse(start + 2, delimIndex, statements); } else if (word.Equals("EXIT")) { // ignore the EXIT command Parse(start + 5, delimIndex, statements); } else if (complexCmds.Contains(word) && IsPackageDef(start + word.Length + 1)) { // parse multi-depth DDL ParseComplex(ref start, statements); if (start < sql.Length) { Parse(start, delimIndex, statements); } } else { // TODO: use start-delimeter[] to determine end point rather than manually // looking for the next semi-colon (which might be embedded in a string) // simple query, seek end int end = IndexOfUnquoted(sql, start, ';'); string query; if (end < 0) { query = sql.Substring(start); } else { query = sql.Substring(start, end - start); } statements.Add(query.Trim()); if (end < 0) { return; } end++; if (end < sql.Length) { Parse(end, delimIndex + 1, statements); } } }