Skip to content

Commit 9d61c30

Browse files
Added SQLCheck as a tool
1 parent 45683a9 commit 9d61c30

28 files changed

+5525
-0
lines changed

SQLCheck/.vs/SQLCheck/v15/Server/sqlite3/db.lock

Whitespace-only changes.
656 KB
Binary file not shown.
32 KB
Binary file not shown.
3.96 MB
Binary file not shown.

SQLCheck/SQLCheck.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 15
4+
VisualStudioVersion = 15.0.28307.1340
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLCheck", "SQLCheck\SQLCheck.csproj", "{42560C3B-F9CE-4E2D-991C-332CF293E2FC}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{42560C3B-F9CE-4E2D-991C-332CF293E2FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{42560C3B-F9CE-4E2D-991C-332CF293E2FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{42560C3B-F9CE-4E2D-991C-332CF293E2FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{42560C3B-F9CE-4E2D-991C-332CF293E2FC}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {2A314081-692A-48DE-AC35-E61C7C331BA1}
24+
EndGlobalSection
25+
EndGlobal

SQLCheck/SQLCheck/Collectors.cs

Lines changed: 2337 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
using System.Collections;
4+
5+
namespace SQLCheck
6+
{
7+
8+
//
9+
// Written by the Microsoft CSS SQL Networking Team
10+
//
11+
// Calling order:
12+
//
13+
// AddRule - n times
14+
// string result = Parse(args) - once, result contains error message or "" if okay
15+
// ArrayList List = GetArgs(argname) - once per arg, returns an ArrayList of 0..n CommandlineArgs
16+
//
17+
// Arguments can have the following prioperties:
18+
//
19+
// Case sensitive or case-insensitive
20+
// Required or optional
21+
// Appear once or many times (or 0 times if optional)
22+
// Have a value or not
23+
// If the arg name is "" then the value must not be proceeded by a flag that requires a value
24+
//
25+
// EXAMPLE USAGE:
26+
//
27+
// appname.exe filename [-out filename] [-g value] [-G] -h value [-flags value [-flags value [...]]]
28+
//
29+
// public ArgRule(argName, hasValue, allowDuplicates = false, caseInsensitive = true, required = true)
30+
// cp.AddRule(new ArgRule("", true, false, true, true)); // file name is required
31+
// cp.AddRule(new ArgRule("flags", true, true, true, false)); // flags is optional but may appear more than once
32+
// cp.AddRule(new ArgRule("out", true, false, true, false)); // out is optional but may only appear once
33+
// cp.AddRule(new ArgRule("g", true, false, false, false)); // g is optional and case-sensitive
34+
// cp.AddRule(new ArgRule("G", false, false, false, false)); // G is optional and takes no value and is case sensitive
35+
// cp.AddRule(new ArgRule("h", true, false, true, true)); // h is required and takes an argument
36+
//
37+
// argements can appear in any order, as long as name/value pairs are adjacent
38+
// arguments other than -g and -G are case-insensitive
39+
// -flags may appear 0..n times
40+
// -G can come before filename
41+
// name value pairs can be: -x=y, -x:y, or -x y
42+
//
43+
44+
class CommandLineParser
45+
{
46+
public ArrayList Args = new ArrayList();
47+
public ArrayList Rules = new ArrayList();
48+
49+
public string Parse(string[] args)
50+
{
51+
string lastToken = "";
52+
string ruleViolation = "";
53+
54+
foreach (string arg in args)
55+
{
56+
string argName = "";
57+
if (arg.StartsWith("-") || arg.StartsWith("/"))
58+
{
59+
string[] parts = null;
60+
argName = arg.Substring(1); // strip leading - or /
61+
62+
//
63+
// process lastToken, if it has a value
64+
//
65+
if (lastToken.Length > 0)
66+
{
67+
if (lastToken.StartsWith("-") || lastToken.StartsWith("/"))
68+
{
69+
ruleViolation = AddArg(lastToken.Substring(1), ""); // switch with no arguments
70+
}
71+
else
72+
{
73+
ruleViolation = AddArg("", lastToken); // switch-less argument
74+
}
75+
if (ruleViolation != "") return ruleViolation;
76+
lastToken = "";
77+
}
78+
79+
//
80+
// does the switch have a value in the same arg ???
81+
//
82+
if (argName.Contains(":") || argName.Contains("="))
83+
{
84+
parts = argName.Split(new char[] {':', '='}, 2);
85+
ruleViolation = AddArg(parts[0], parts[1]); // switch with argument separated by : or =
86+
if (ruleViolation != "") return ruleViolation;
87+
}
88+
else
89+
{
90+
lastToken = arg; // switch - argument may be in next arg - wait for next iteration
91+
}
92+
}
93+
else // switchless argument - process lastToken
94+
{
95+
if (lastToken.Length > 0)
96+
{
97+
if (lastToken.StartsWith("-") || lastToken.StartsWith("/"))
98+
{
99+
//
100+
// Should the switch take an argument?
101+
//
102+
lastToken = lastToken.Substring(1); // trim - or /
103+
ArgRule r = GetArgRule(lastToken);
104+
if (r.fHasValue)
105+
{
106+
ruleViolation = AddArg(lastToken, arg); // switch with value in next argument
107+
if (ruleViolation != "") return ruleViolation;
108+
lastToken = "";
109+
}
110+
else
111+
{
112+
ruleViolation = AddArg(lastToken, ""); // switch takes no arguments, promote arg to lastToken
113+
if (ruleViolation != "") return ruleViolation;
114+
lastToken = arg;
115+
}
116+
}
117+
else
118+
{
119+
ruleViolation = AddArg("", lastToken); // switch-less argument
120+
if (ruleViolation != "") return ruleViolation;
121+
lastToken = "";
122+
}
123+
}
124+
else
125+
{
126+
lastToken = arg;
127+
}
128+
}
129+
}
130+
131+
//
132+
// Process lastToken if one exists
133+
//
134+
if (lastToken.Length > 0)
135+
{
136+
if (lastToken.StartsWith("-") || lastToken.StartsWith("/"))
137+
{
138+
ruleViolation = AddArg(lastToken.Substring(1), ""); // switch takes no arguments, promote arg to lastToken
139+
if (ruleViolation != "") return ruleViolation;
140+
}
141+
else
142+
{
143+
ruleViolation = AddArg("", lastToken); // switch-less argument
144+
if (ruleViolation != "") return ruleViolation;
145+
}
146+
}
147+
148+
if (ruleViolation != "") return ruleViolation;
149+
150+
//
151+
// Evaluate missing required switches
152+
//
153+
154+
foreach (ArgRule r in Rules)
155+
{
156+
if (r.fMustAppear && (GetArgs(r.name).Count == 0))
157+
{
158+
if (r.name == "")
159+
return @"Required value is missing.";
160+
else
161+
return @"Required switch " + r.name + " is missing.";
162+
}
163+
}
164+
165+
return "";
166+
}
167+
168+
private string AddArg(string name, string value)
169+
{
170+
// check rules
171+
ArgRule r = GetArgRule(name);
172+
if (r == null && name == "") return @"Invalid argument: " + value;
173+
if (r == null) return @"Invalid switch: " + name;
174+
175+
if (r.fInsensitive) name = name.ToLower();
176+
177+
if (r.fDuplicates == false) if (GetArgs(name).Count > 0)
178+
{
179+
if (name == "")
180+
return @"A switch-less value can only appear once.";
181+
else
182+
return @"Switch " + name + " can only appear once.";
183+
}
184+
if (r.fHasValue == false) if (value != "") return @"Switch " + name + " does not take an argument.";
185+
if (r.fHasValue == true) if (value == "") return @"Switch " + name + " requires an argument.";
186+
//
187+
// if fall through, we add the argument
188+
//
189+
if (value == "") value = "true";
190+
CommandLineArgs a = new CommandLineArgs();
191+
a.name = name;
192+
a.value = value;
193+
Args.Add(a);
194+
return "";
195+
}
196+
197+
public ArrayList GetArgs(string name)
198+
{
199+
ArrayList outList = new ArrayList();
200+
foreach (CommandLineArgs a in Args)
201+
{
202+
if (a.name == name)
203+
outList.Add(a);
204+
}
205+
return outList;
206+
}
207+
208+
private ArgRule GetArgRule(string name)
209+
{
210+
foreach (ArgRule r in Rules)
211+
{
212+
if (r.name == name)
213+
return r;
214+
if (r.fInsensitive && (r.name.ToLower() == name.ToLower()))
215+
return r;
216+
}
217+
return null;
218+
}
219+
220+
public void AddRule(ArgRule r)
221+
{
222+
Rules.Add(r);
223+
}
224+
}
225+
226+
public class CommandLineArgs
227+
{
228+
public string name = "";
229+
public string value = "";
230+
}
231+
232+
public class ArgRule
233+
{
234+
public string name = "";
235+
public bool fHasValue = false;
236+
public bool fDuplicates = false;
237+
public bool fInsensitive = true;
238+
public bool fMustAppear = true;
239+
240+
public ArgRule(string argName, bool hasValue, bool allowDuplicates = false, bool caseInsensitive = true, bool required = true)
241+
{
242+
name = caseInsensitive ? argName.ToLower() : argName;
243+
fHasValue = hasValue;
244+
fDuplicates = allowDuplicates;
245+
fInsensitive = caseInsensitive;
246+
fMustAppear = required;
247+
}
248+
}
249+
}

0 commit comments

Comments
 (0)