Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>2009-04-08 05:49:51 +0400
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>2009-04-08 05:49:51 +0400
commit1ac8a9bda72652ff63ce1fb1e3de3be0df5478c8 (patch)
tree27327b5e2bf5d36f8d8cc1a596cc1ce4d8272aaf /webcompare
parent90a3857a62f2b85b4f0622ed0192d9bd5757aa9b (diff)
2009-04-07 Gonzalo Paniagua Javier <gonzalo@novell.com>
* db/init-db.mysql: new filters table. And modifications to add the detail level field. * App_Code/NodeUtils.cs: * App_Code/CompareParameters.cs: updated to add DetailLevel * db/webcompare-db.cs: for every compare, generate 'raw' data and 'filtered' data. The filters are read from the DB. * INSTALL: updated. * main.css: 'detaillevel' CSS * status.aspx: added a RadioButtonList to select between the normal and the detailed view of a tree. Default is 'normal'. svn path=/trunk/mono-tools/; revision=131269
Diffstat (limited to 'webcompare')
-rw-r--r--webcompare/App_Code/CompareParameters.cs6
-rw-r--r--webcompare/App_Code/NodeUtils.cs10
-rw-r--r--webcompare/INSTALL31
-rw-r--r--webcompare/db/init-db.mysql73
-rw-r--r--webcompare/db/webcompare-db.cs114
-rw-r--r--webcompare/main.css14
-rw-r--r--webcompare/status.aspx73
7 files changed, 292 insertions, 29 deletions
diff --git a/webcompare/App_Code/CompareParameters.cs b/webcompare/App_Code/CompareParameters.cs
index a6283c7d..a4da134f 100644
--- a/webcompare/App_Code/CompareParameters.cs
+++ b/webcompare/App_Code/CompareParameters.cs
@@ -40,6 +40,7 @@ public class CompareParameters {
Assembly = nvc ["assembly"] ?? "mscorlib";
InfoDir = nvc ["reference"] ?? "3.5";
profile = nvc ["profile"] ?? "2.0";
+ detail_level = nvc ["detail_level"] ?? "normal";
Validate (profile);
BinDir = "binary/" + profile;
}
@@ -60,6 +61,11 @@ public class CompareParameters {
get { return profile; }
}
+ string detail_level;
+ public string DetailLevel {
+ get { return detail_level; }
+ }
+
string assembly;
public string Assembly {
get { return assembly; }
diff --git a/webcompare/App_Code/NodeUtils.cs b/webcompare/App_Code/NodeUtils.cs
index bc26c9d0..f411e232 100644
--- a/webcompare/App_Code/NodeUtils.cs
+++ b/webcompare/App_Code/NodeUtils.cs
@@ -54,6 +54,7 @@ public class NodeUtils {
string profile;
string assembly;
int master_id;
+ string detail_level;
static NodeUtils ()
{
@@ -61,7 +62,7 @@ public class NodeUtils {
cnc_string = col ["WebCompareDB"];
}
- public NodeUtils (string reference, string profile, string assembly)
+ public NodeUtils (string reference, string profile, string assembly, string detail_level)
{
if (String.IsNullOrEmpty (reference))
throw new ArgumentNullException ("reference");
@@ -69,10 +70,16 @@ public class NodeUtils {
throw new ArgumentNullException ("profile");
if (String.IsNullOrEmpty (assembly))
throw new ArgumentNullException ("assembly");
+ if (String.IsNullOrEmpty (detail_level))
+ throw new ArgumentNullException ("detail_level");
+
+ if (detail_level != "normal" && detail_level != "detailed")
+ throw new ArgumentException ("detail_level", "Invalid value");
this.reference = reference;
this.profile = profile;
this.assembly = assembly;
+ this.detail_level = detail_level;
master_id = -1;
}
@@ -85,6 +92,7 @@ public class NodeUtils {
AddParameter (cmd, "reference", reference);
AddParameter (cmd, "profile", profile);
AddParameter (cmd, "assembly", assembly);
+ AddParameter (cmd, "detail_level", detail_level);
master_id = Convert.ToInt32 (cmd.ExecuteScalar ());
return master_id;
}
diff --git a/webcompare/INSTALL b/webcompare/INSTALL
index 992c6158..94fdd5e1 100644
--- a/webcompare/INSTALL
+++ b/webcompare/INSTALL
@@ -31,14 +31,33 @@ Prerequisites
MySQL configuration
--------------------
* Create a database (i.e. 'webcompare').
+
+ * Run the init-db.mysql script in MySql:
+ mysql> source init-db.mysql
+
* Create and assign privileges to the web application DB user like:
- mysql> GRANT SELECT,EXECUTE on `webcompare`.* TO `webcompare`@`localhost`;
- mysql> GRANT SELECT on `mysql`.`proc` TO `webcompare`@`localhost`;
- mysql> SET PASSWORD FOR `webcompare`@`localhost` = PASSWORD ('thepassword');
+ mysql> GRANT SELECT,EXECUTE on `webcompare`.* TO `webcompare`@`localhost`;
+ mysql> GRANT SELECT on `mysql`.`proc` TO `webcompare`@`localhost`;
+ mysql> SET PASSWORD FOR `webcompare`@`localhost` = PASSWORD ('thepassword');
+
* Create the user for the webcompare-db.exe application:
- mysql> GRANT ALL on `webcompare`.* TO `dbupdater`@`localhost`;
- mysql> SET PASSWORD FOR `dbupdater`@`localhost` = PASSWORD ('apassword');
- mysql> GRANT FILE ON *.* TO `dbupdater`@`localhost`;
+ mysql> GRANT ALL on `webcompare`.* TO `dbupdater`@`localhost`;
+ mysql> SET PASSWORD FOR `dbupdater`@`localhost` = PASSWORD ('apassword');
+ mysql> GRANT FILE ON *.* TO `dbupdater`@`localhost`;
+
+ * Add any filters that you want on the full compare to generate the 'normal' view:
+ mysql> INSERT INTO filters VALUES (NULL, 0, 'name_str', 'typename_str');
+ mysql> INSERT INTO filters VALUES (NULL, 0, 'name_str', NULL);
+ mysql> INSERT INTO filters VALUES (NULL, 0, NULL, 'typename_str');
+ mysql> INSERT INTO filters VALUES (NULL, 1, 'regex_name', 'regex_typename');
+ mysql> INSERT INTO filters VALUES (NULL, 1, 'regex_name', NULL);
+ mysql> INSERT INTO filters VALUES (NULL, 1, NULL, 'regex_typename');
+
+ -The first column should always be inserted as NULL.
+ -The second column is 0 for string and 1 for Regex.
+ -The third column is the string/Regex to match the 'name'
+ -The forth column is the string/Regex to match the 'typename'
+ -A NULL for the 3rd/4rd column matches a NULL in the input data.
Web app configuration
diff --git a/webcompare/db/init-db.mysql b/webcompare/db/init-db.mysql
index f7b177ee..4ba70b7f 100644
--- a/webcompare/db/init-db.mysql
+++ b/webcompare/db/init-db.mysql
@@ -86,3 +86,76 @@ CREATE TABLE `nodes` (
) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin;
SET character_set_client = @saved_cs_client;
+#### Changes 1###########3
+ALTER TABLE `webcompare`.`master` ADD COLUMN `detail_level` VARCHAR(25) NOT NULL AFTER `assembly`,
+DROP INDEX `master_idx_1`,
+ADD INDEX `master_idx_1` USING BTREE(`reference`, `profile`, `assembly`, `detail_level`);
+
+DELIMITER $$
+
+DROP PROCEDURE IF EXISTS `webcompare`.`get_master_id`$$
+CREATE DEFINER=`root`@`localhost` PROCEDURE `get_master_id`(in reference varchar(100), in profile varchar (100), in assembly varchar(100), in detail_level varchar (25))
+BEGIN
+SELECT m.id FROM master m
+WHERE m.reference = reference AND m.profile = profile AND m.assembly = assembly AND m.detail_level = detail_level
+ORDER BY last_updated DESC
+LIMIT 1;
+
+END$$
+
+DELIMITER ;
+
+DELIMITER $$
+
+DROP PROCEDURE IF EXISTS `webcompare`.`insert_master`$$
+CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_master`( IN reference varchar(100), IN profile varchar (100), IN assembly varchar (100), IN detail_level VARCHAR(25), IN last_updated timestamp, OUT id int)
+BEGIN
+INSERT INTO master (reference, profile, assembly, detail_level, last_updated, active) VALUES (reference, profile, assembly, detail_level, last_updated, FALSE);
+SET id = LAST_INSERT_ID();
+END$$
+
+DELIMITER ;
+
+
+DELIMITER $$
+
+DROP PROCEDURE IF EXISTS `webcompare`.`update_active_master`$$
+CREATE DEFINER=`root`@`localhost` PROCEDURE `update_active_master`(IN master_id INT)
+BEGIN
+DECLARE reference varchar(128);
+DECLARE profile varchar(128);
+DECLARE assembly varchar(128);
+DECLARE detail_level varchar(25);
+
+SELECT m.reference, m.profile, m.assembly, m.detail_level
+FROM master m
+WHERE m.id = master_id
+INTO @reference, @profile, @assembly, @detail_level;
+
+UPDATE master m
+SET m.active = TRUE
+WHERE m.id = master_id;
+
+UPDATE master m
+SET m.active = FALSE
+WHERE m.id <> master_id AND m.reference = @reference AND m.profile = @profile AND m.assembly = @assembly AND m.detail_level = @detail_level;
+END$$
+
+DELIMITER ;
+
+CREATE TABLE `webcompare`.`filters` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `is_rx` bit NOT NULL,
+ `name_filter` varchar(100) ,
+ `typename_filter` varchar(100) ,
+ PRIMARY KEY (`id`)
+)
+ENGINE = MyISAM;
+
+INSERT INTO filters (is_rx, name_filter, typename_filter) VALUES
+ (0, 'System.ComponentModel.BrowsableAttribute', NULL),
+ (0, 'System.ComponentModel.EditorBrowsableAttribute', NULL),
+ (0, 'System.ComponentModel.DesignerSerializationVisibilityAttribute', NULL),
+ (0, 'System.ComponentModel.DesignerAttribute', NULL),
+ (1, '^System.Diagnostics.Debug.*', NULL);
+
diff --git a/webcompare/db/webcompare-db.cs b/webcompare/db/webcompare-db.cs
index 5df16dfe..7c4c9775 100644
--- a/webcompare/db/webcompare-db.cs
+++ b/webcompare/db/webcompare-db.cs
@@ -34,6 +34,7 @@ using System.Data;
using System.IO;
using System.Linq;
using System.Text;
+using System.Text.RegularExpressions;
using System.Threading;
using MySql.Data.MySqlClient;
using GuiCompare;
@@ -135,6 +136,12 @@ class Populate {
state.UpdateLock.WaitOne ();
if (state.Root != null) {
Console.WriteLine ("Inserting {0} {1} {2}", state.Reference, state.Profile, state.Assembly);
+ state.DetailLevel = "detailed";
+ InsertRoot (state);
+ state.Root.ResetCounts ();
+ FilterRoot (state.Root);
+ state.Root.PropagateCounts ();
+ state.DetailLevel = "normal";
InsertRoot (state);
} else {
Console.WriteLine ("No insertions for {0} {1} {2}", state.Reference, state.Profile, state.Assembly);
@@ -145,7 +152,7 @@ class Populate {
}
}
- static IDbConnection GetConnection ()
+ public static IDbConnection GetConnection ()
{
IDbConnection cnc = new MySqlConnection ();
cnc.ConnectionString = cnc_string;
@@ -204,6 +211,7 @@ class Populate {
AddParameter (cmd, "reference", state.Reference);
AddParameter (cmd, "profile", state.Profile);
AddParameter (cmd, "assembly", state.Assembly);
+ AddParameter (cmd, "detail_level", state.DetailLevel);
AddParameter (cmd, "last_updated", state.AssemblyLastWrite);
IDataParameter p = AddOutputParameter (cmd, "id");
cmd.ExecuteNonQuery ();
@@ -401,6 +409,44 @@ class Populate {
return "\\N";
return str.Replace ("\t", "\\\t").Replace ('\n', ' ').Replace ('\r', ' ');
}
+
+ static void FilterRoot (ComparisonNode node)
+ {
+ Filters filters = null;
+ using (IDbConnection cnc = Populate.GetConnection ()) {
+ IDbCommand cmd = cnc.CreateCommand ();
+ cmd.CommandText = "SELECT is_rx, name_filter, typename_filter FROM filters";
+ using (IDataReader reader = cmd.ExecuteReader ()) {
+ filters = new Filters (reader);
+ }
+ }
+
+ FilterNode (filters, node);
+ }
+
+ static bool FilterNode (Filters filters, ComparisonNode node)
+ {
+ if (filters.Filter (node.Name, node.TypeName)) {
+ Console.WriteLine ("OUT: '{0}' '{1}'", node.Name, node.TypeName);
+ return true;
+ }
+
+ List<ComparisonNode> removed = null;
+ foreach (ComparisonNode child in node.Children) {
+ if (FilterNode (filters, child)) {
+ if (removed == null)
+ removed = new List<ComparisonNode> ();
+ removed.Add (child);
+ }
+ }
+ if (removed == null)
+ return false;
+
+ foreach (ComparisonNode child in removed)
+ node.Children.Remove (child);
+
+ return false;
+ }
}
class State {
@@ -422,6 +468,8 @@ class State {
public StreamWriter MessagesWriter;
public int MasterId;
+ public string DetailLevel;
+
public State (string reference, string profile, string assembly, string info_file, string dll_file)
{
Reference = reference;
@@ -439,3 +487,67 @@ class State {
}
}
+class Filters {
+ const RegexOptions rx_options = RegexOptions.Compiled;
+ // -null matches null
+ // -"*" matches any string, including null
+ List<string []> static_filters;
+
+ // -null matches null
+ List<Regex []> rx_filters;
+
+ public Filters (IDataReader reader)
+ {
+ static_filters = new List<string[]> ();
+ rx_filters = new List<Regex []> ();
+ while (reader.Read ()) {
+ string name_filter = reader ["name_filter"] as string;
+ string typename_filter = reader ["typename_filter"] as string;
+ if (false == Convert.ToBoolean (reader ["is_rx"]))
+ static_filters.Add (new string [] { name_filter, typename_filter });
+ else {
+ Regex [] rxs = new Regex [2];
+ if (name_filter != null)
+ rxs [0] = new Regex (name_filter, rx_options);
+ if (typename_filter != null)
+ rxs [1] = new Regex (typename_filter, rx_options);
+ rx_filters.Add (rxs);
+ }
+ }
+ }
+
+ public bool Filter (string name, string typename)
+ {
+ bool match = false;
+ foreach (string [] strs in static_filters) {
+ string s1 = strs [0];
+ string s2 = strs [1];
+ if (s2 == "*")
+ match = (s1 == strs [0]);
+ else if (s1 == "*")
+ match = (s2 == strs [1]);
+ else
+ match = (name == s1 && typename == s2);
+
+ if (match)
+ return true;
+ }
+
+ foreach (Regex [] rx in rx_filters) {
+ Regex rx1 = rx [0];
+ Regex rx2 = rx [1];
+ if (rx1 != null && rx2 != null && rx1.IsMatch (name) && rx2.IsMatch (typename))
+ match = true;
+ else if (rx1 != null && typename == null && rx1.IsMatch (name))
+ match = true;
+ else if (rx2 != null && name == null && rx2.IsMatch (typename))
+ match = true;
+
+ if (match)
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/webcompare/main.css b/webcompare/main.css
index 3ecd1c27..4bc33334 100644
--- a/webcompare/main.css
+++ b/webcompare/main.css
@@ -91,3 +91,17 @@ a:active { color:#ccf; text-decoration: none; }
background-image: url(images/st.gif);
}
+#treeview {
+ float: left;
+}
+#detaillevel {
+ float: right;
+ margin: 20px 20px 20px 20px;
+ border-width: 1px 1px 2px 2px;
+ border-color: #4c83c4;
+ border-style: solid;
+ display: block;
+ background-color: #DDD;
+ padding: 1em;
+}
+
diff --git a/webcompare/status.aspx b/webcompare/status.aspx
index cf287848..5126e00c 100644
--- a/webcompare/status.aspx
+++ b/webcompare/status.aspx
@@ -24,7 +24,7 @@ NodeUtils db;
NodeUtils DB {
get {
if (db == null)
- db = new NodeUtils (Parameters.InfoDir, Parameters.Profile, Parameters.Assembly);
+ db = new NodeUtils (Parameters.InfoDir, Parameters.Profile, Parameters.Assembly, Parameters.DetailLevel);
return db;
}
}
@@ -32,15 +32,19 @@ NodeUtils DB {
static string ImageTodo (ComparisonNode cn)
{
- return String.Format ("<img src='images/st.gif' border=0 align=absmiddle title='{0}'>", GetTodo (cn));
+ string todo = GetTodo (cn);
+ if (!String.IsNullOrEmpty (todo))
+ todo = HttpUtility.HtmlEncode (todo);
+ return String.Format ("<img src='images/st.gif' border=0 align=absmiddle title=\"{0}\">", todo);
}
static string Get (int count, string kind, string caption)
{
if (count == 0)
return "";
-
- return String.Format ("<div class='report' title='{0} {2}'><div class='icons suffix {1}'></div>{0}</div>", count, kind, caption);
+
+ caption = HttpUtility.HtmlEncode (caption);
+ return String.Format ("<div class='report' title=\"{0} {2}\"><div class='icons suffix {1}'></div>{0}</div>", count, kind, caption);
}
static string GetStatus (ComparisonNode n)
@@ -63,13 +67,22 @@ public void Page_Load ()
if (IsPostBack)
return;
+ Header.Title = String.Format ("Mono {1} in {0} vs MS.NET {2}", Parameters.InfoDir, Parameters.Assembly, Parameters.Profile);
+ page_header.InnerText = Header.Title;
+
+ string detail = Request.QueryString ["detail_level"];
+ if (String.IsNullOrEmpty (detail) || detail != "detailed")
+ detail = "normal";
+
+ dlevel.SelectedValue = detail;
var cp = Parameters;
var n = DB.GetRootNode ();
if (n == null) {
tree.Visible = false;
tree.Enabled = false;
time_label.Text = "No data available for " +
- String.Format ("Mono <b>{1}</b> in {0} vs MS.NET {2}", Parameters.InfoDir, Parameters.Assembly, Parameters.Profile);
+ HttpUtility.HtmlEncode (String.Format ("Mono <b>{1}</b> in {0} vs MS.NET {2}",
+ Parameters.InfoDir, Parameters.Assembly, Parameters.Profile));
return;
}
@@ -89,9 +102,7 @@ public void Page_Load ()
else
t = String.Format ("{0} seconds", diff.Seconds);
- time_label.Text = String.Format ("Assembly <b>{1}</b> last updated: {0} ago", t, Parameters.Assembly);
- Header.Title = String.Format ("Mono {1} in {0} vs MS.NET {2}", Parameters.InfoDir, Parameters.Assembly, Parameters.Profile);
- page_header.InnerText = Header.Title;
+ time_label.Text = String.Format ("Assembly <b>{1}</b> last updated: {0} ago", t, HttpUtility.HtmlEncode (Parameters.Assembly));
}
static string GetTodo (ComparisonNode cn)
@@ -123,17 +134,19 @@ static string GetMessages (ComparisonNode cn)
static string ImagesFromCounts (ComparisonNode cn)
{
int x = (cn.Todo != 0 ? 2 : 0) | (cn.Warning != 0 ? 1 : 0);
- switch (x){
+ switch (x) {
case 0:
- return "";
+ return null;
case 1:
return ImageWarning;
case 2:
return ImageTodo (cn);
case 4:
return ImageTodo (cn) + ImageWarning;
+ default:
+ break;
}
- return "";
+ return null;
}
static string MemberStatus (ComparisonNode cn)
@@ -145,16 +158,16 @@ static string MemberStatus (ComparisonNode cn)
switch (cn.Status) {
case ComparisonStatus.None:
- return counts == "" ? ImageOk : ImageOk + counts;
+ return ImageOk + counts;
case ComparisonStatus.Missing:
return ImageMissing;
case ComparisonStatus.Extra:
- return counts == "" ? ImageExtra : ImageOk + counts;
+ return ImageExtra + counts;
case ComparisonStatus.Error:
- return counts == "" ? ImageError : ImageError + counts;
+ return ImageError + counts;
default:
return "Unknown status: " + cn.Status;
@@ -311,6 +324,17 @@ void TreeNodePopulate (object sender, TreeNodeEventArgs e)
e.Node.ChildNodes.Add (tn);
}
}
+
+void OnLevelChanged (object sender, EventArgs args)
+{
+ if (dlevel.SelectedIndex < 0)
+ return;
+
+ string url = String.Format ("{0}?reference={1}&profile={2}&assembly={3}&detail_level={4}", Request.FilePath,
+ Parameters.InfoDir, Parameters.Profile, Parameters.Assembly, dlevel.SelectedValue);
+ Response.Redirect (url);
+}
+
</script>
<html>
<head id="head1" runat="server">
@@ -322,21 +346,28 @@ void TreeNodePopulate (object sender, TreeNodeEventArgs e)
<h1 runat="server" id="page_header">Mono Class Status Pages</h1>
</div>
<form id="form" runat="server">
- <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div id="content">
- <br>
- <asp:Label id="time_label" runat="server"/>
- <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
- <ContentTemplate>
+ <div id="treeview">
+ <br>
+ <asp:Label id="time_label" runat="server"/>
<asp:TreeView ID="tree" Runat="server"
OnTreeNodePopulate="TreeNodePopulate"
EnableClientScript="true"
PopulateNodesFromClient="true"
ExpandDepth="1">
</asp:TreeView>
- </ContentTemplate>
- </asp:UpdatePanel>
</div>
+ <div id="detaillevel">
+ <div style="font-weight: bold; margin-bottom: 0.5em; text-align: center;">Detail Level</div>
+ <asp:RadioButtonList id="dlevel" runat="server"
+ AutoPostBack="true"
+ RepeatDirection="vertical"
+ OnSelectedIndexChanged="OnLevelChanged">
+ <asp:ListItem Text="Normal" Value="normal" Selected="true" />
+ <asp:ListItem Text="Detailed" Value="detailed" />
+ </asp:RadioButtonList>
+ </div>
+ </div>
</form>
</body>
</html>