public FrontPageResponse GetFrontPageDataWithTags (WebServiceLogin login, int page_size, int page, string [] lanes, int [] lane_ids, int latest_days, string[] tags) { FrontPageResponse response = new FrontPageResponse (); List<DBLane> Lanes; List<DBHost> Hosts; List<DBHostLane> HostLanes; List<int> TaggedLaneIds = null; log.DebugFormat ("GetFrontPageDataWithTags (page_size: {0} page: {1} lanes: {2} lane_ids: {3} latest_days: {4} tags: {5})", page_size, page, lanes == null ? "null" : lanes.Length.ToString (), lane_ids == null ? "null" : lane_ids.Length.ToString (), latest_days, tags == null ? "null" : tags.Length.ToString ()); page_size = Math.Min (page_size, 500); string single_lane = string.Empty; if ((lanes != null && lanes.Length == 1)) single_lane = lanes [0]; using (DB db = new DB ()) { Authenticate (db, login, response, true); using (IDbCommand cmd = db.CreateCommand ()) { var latest_only = latest_days != 0; var last_month = string.Empty; if (!string.IsNullOrEmpty (single_lane)) { // this will ignore the @afterdate condition below if the selected lane is not a parent of other lanes last_month = " AND (NOT EXISTS (SELECT id FROM Lane WHERE parent_lane_id = (SELECT id FROM Lane WHERE lane = @single_lane)) OR \n"; DB.CreateParameter (cmd, "single_lane", single_lane); } else { last_month = " AND ("; } last_month += @" ( EXISTS (SELECT id FROM Revision WHERE date > @afterdate AND lane_id = Lane.id) OR EXISTS (SELECT id FROM RevisionWork WHERE lane_id = Lane.id AND ((completed = TRUE AND endtime > @afterdate) OR (state <> 9 AND state <> 11 AND completed = FALSE))) OR NOT EXISTS (SELECT id FROM Revision WHERE lane_id = Lane.id) OR EXISTS (SELECT id FROM Lane AS ParentLane WHERE ParentLane.parent_lane_id = Lane.id) ))"; /* */ cmd.CommandText = "SELECT * FROM Lane WHERE enabled = TRUE"; if (latest_only) cmd.CommandText += last_month; cmd.CommandText += ";\n"; cmd.CommandText += "SELECT * FROM Host;\n"; cmd.CommandText += @" SELECT HostLane.* FROM HostLane INNER JOIN Lane ON Lane.id = HostLane.lane_id WHERE hidden = false AND Lane.enabled = TRUE"; if (latest_only) cmd.CommandText += last_month; cmd.CommandText += ";\n"; if (latest_only) DB.CreateParameter (cmd, "afterdate", DateTime.Now.AddDays (-latest_days)); if (tags != null && tags.Length > 0) { cmd.CommandText += "SELECT DISTINCT lane_id FROM LaneTag WHERE "; for (int i = 0; i < tags.Length; i++) { if (i > 0) cmd.CommandText += " OR "; cmd.CommandText += " tag = @tag" + i.ToString (); DB.CreateParameter (cmd, "tag" + i.ToString (), tags [i]); } cmd.CommandText += ";"; } cmd.CommandText = "SET enable_seqscan = false;\n" + cmd.CommandText + "\nSET enable_seqscan = true;\n"; using (IDataReader reader = cmd.ExecuteReader ()) { Lanes = DBRecord.LoadMany<DBLane> (reader); reader.NextResult (); Hosts = DBRecord.LoadMany<DBHost> (reader); reader.NextResult (); HostLanes = DBRecord.LoadMany<DBHostLane> (reader); if (tags != null && tags.Length > 0) { reader.NextResult (); TaggedLaneIds = new List<int> (tags.Length); while (reader.Read ()) TaggedLaneIds.Add (reader.GetInt32 (0)); } } } // get a list of the lanes to show // note that the logic here is slightly different from the usual "string lane, int? lane_id" logic in other methods, // where we only use the string parameter if the id parameter isn't provided, here we add everything we can to the // list of selected lanes, so if you provide both a string and an id parameter both are used (assuming they correspond // with different lanes of course). response.SelectedLanes = Lanes.FindAll (delegate (DBLane l) { if (lane_ids != null) { for (int i = 0; i < lane_ids.Length; i++) { if (lane_ids [i] == l.id) return true; } } if (lanes != null) { for (int i = 0; i < lanes.Length; i++) { if (!string.IsNullOrEmpty (lanes [i]) && lanes [i] == l.lane) return true; } } if (TaggedLaneIds != null) { if (TaggedLaneIds.Contains (l.id)) return true; } return false; }); log.DebugFormat ("We have {0} selected lanes", response.SelectedLanes.Count); // backwards compat if (response.SelectedLanes.Count == 1) response.Lane = response.SelectedLanes [0]; response.RevisionWorkViews = new List<List<DBRevisionWorkView2>> (HostLanes.Count); response.RevisionWorkHostLaneRelation = new List<int> (HostLanes.Count); if (HostLanes.Count > 0) { using (IDbCommand cmd = db.CreateCommand ()) { // FIXME: use this instead: https://gist.github.com/rolfbjarne/cf73bf22209c8a8ef844 for (int i = 0; i < HostLanes.Count; i++) { DBHostLane hl = HostLanes [i]; var stri = i.ToString (); cmd.CommandText += @"SELECT R.* FROM (" + DBRevisionWorkView2.SQL.Replace (';', ' ') + ") AS R WHERE " + "R.host_id = @host_id" + stri + " AND R.lane_id = @lane_id" + stri + " LIMIT @limit OFFSET @offset;\n"; DB.CreateParameter (cmd, "host_id" + stri, hl.host_id); DB.CreateParameter (cmd, "lane_id" + stri, hl.lane_id); response.RevisionWorkHostLaneRelation.Add (hl.id); } DB.CreateParameter (cmd, "limit", page_size); DB.CreateParameter (cmd, "offset", page * page_size); using (IDataReader reader = cmd.ExecuteReader ()) { do { response.RevisionWorkViews.Add (DBRecord.LoadMany<DBRevisionWorkView2> (reader)); } while (reader.NextResult ()); } } } // Create a list of all the lanes which have hostlanes var enabled_set = new HashSet<int> (); foreach (DBHostLane hl in HostLanes) { if (enabled_set.Contains (hl.lane_id)) continue; enabled_set.Add (hl.lane_id); // Walk up the tree of parent lanes, marking all the parents too var l = Lanes.FirstOrDefault ((v) => v.id == hl.lane_id); if (l == null) { log.WarnFormat ("GetFrontPageDataWithTags: could not find lane {0} for host lane {1}", hl.lane_id, hl.id); l = DBLane_Extensions.Create (db, hl.lane_id); l.enabled = true; // This will prevent us from having to load the lane manually again. l.Save (db); Lanes.Add (l); continue; } while (true) { if (!l.parent_lane_id.HasValue) break; if (enabled_set.Contains (l.parent_lane_id.Value)) break; enabled_set.Add (l.parent_lane_id.Value); var old_l = l; l = Lanes.FirstOrDefault ((v) => v.id == l.parent_lane_id.Value); if (l == null) { log.WarnFormat ("GetFrontPageDataWithTags: could not find parent lane {0} for lane {1} (host lane {2})", old_l.parent_lane_id.Value, old_l.id, hl.id); l = DBLane_Extensions.Create (db, old_l.parent_lane_id.Value); l.enabled = true; // This will prevent us from having to load the lane manually again. l.Save (db); Lanes.Add (l); break; } } } // Remove the lanes which aren't marked for (int i = Lanes.Count - 1; i >= 0; i--) { if (!enabled_set.Contains (Lanes [i].id)) { Lanes.RemoveAt (i); } } response.Lanes = Lanes; response.Hosts = Hosts; response.HostLanes = HostLanes; } return response; }
private Dictionary<string, object> RevisionWorkToDict(FrontPageResponse data, DBLane l, DBRevisionWorkView2 w) { return new Dictionary<string, object> { { "id", w.id }, { "author", w.author }, { "host_id", w.host_id }, { "host", data.Hosts.Find( h => h.id == w.host_id).host }, { "revision", w.revision }, { "revision_id", w.revision_id }, { "completed", w.completed }, { "status", w.state.ToString().ToLowerInvariant() }, { "endtime", w.endtime }, { "date", w.date }, { "lane", l.lane }, { "repository", l.repository }, { "branch", l.max_revision } }; }
List<DBRevisionWorkView2> FindRevisionWorkViews (FrontPageResponse data, int hostlane_id) { for (int k = 0; k < data.RevisionWorkHostLaneRelation.Count; k++) { if (data.RevisionWorkHostLaneRelation [k] == hostlane_id) return data.RevisionWorkViews [k]; } return null; }
public string GenerateOverview (FrontPageResponse data) { StringBuilder matrix = new StringBuilder (); LaneTreeNode tree = BuildTree (data); List<StringBuilder> header_rows = new List<StringBuilder> (); List<int> hostlane_order = new List<int> (); if (tree == null) return string.Empty; WriteLanes (header_rows, tree, 0, tree.Depth); matrix.AppendLine ("<table class='buildstatus'>"); for (int i = 0; i < header_rows.Count; i++) { if (header_rows [i].Length == 0) continue; matrix.Append ("<tr>"); matrix.Append (header_rows [i]); matrix.AppendLine ("</tr>"); } matrix.AppendLine ("<tr>"); WriteHostLanes (matrix, tree, data.Hosts, hostlane_order); matrix.AppendLine ("</tr>"); int counter = 0; int added = 0; StringBuilder row = new StringBuilder (); do { added = 0; row.Length = 0; for (int i = 0; i < hostlane_order.Count; i++) { int hl_id = hostlane_order [i]; List<DBRevisionWorkView2> rev = null; DBRevisionWorkView2 work = null; for (int k = 0; k < data.RevisionWorkHostLaneRelation.Count; k++) { if (data.RevisionWorkHostLaneRelation [k] == hl_id) { rev = data.RevisionWorkViews [k]; break; } } if (rev != null && rev.Count > counter) { work = rev [counter]; added++; } if (work != null) { string revision = work.revision; int lane_id = work.lane_id; int host_id = work.host_id; int revision_id = work.revision_id; DBState state = work.State; bool completed = work.completed; string state_str = state.ToString ().ToLowerInvariant (); bool is_working; string str_date = string.Empty; if (work.endtime.Year > 2000) str_date = "</br>" + TimeDiffToString (work.endtime, DateTime.UtcNow); switch (state) { case DBState.Executing: is_working = true; break; case DBState.NotDone: case DBState.Paused: case DBState.DependencyNotFulfilled: case DBState.Ignore: is_working = false; break; default: is_working = !completed; break; } long dummy; if (revision.Length > 16 && !long.TryParse (revision, out dummy)) revision = revision.Substring (0, 8); if (is_working) { row.AppendFormat ( @"<td class='{1}'> <center> <table class='executing'> <td> <a href='ViewLane.aspx?lane_id={2}&host_id={3}&revision_id={4}' title='{5}'>{0}{6}</a> </td> </table> <center> </td>", revision, state_str, lane_id, host_id, revision_id, "", str_date); } else { row.AppendFormat ("<td class='{1}'><a href='ViewLane.aspx?lane_id={2}&host_id={3}&revision_id={4}' title='{5}'>{0}{6}</a></td>", revision, state_str, lane_id, host_id, revision_id, "", str_date); } } else { row.Append ("<td>-</td>"); } } if (added > 0 && row.Length > 0) { matrix.Append ("<tr>"); matrix.Append (row.ToString ()); matrix.Append ("</tr>"); } counter++; } while (counter <= limit && added > 0); matrix.AppendLine ("</table>"); return matrix.ToString (); }
private List<Dictionary<string, object>> RenderHostList(FrontPageResponse data, DBLane l, DBHostLane hl) { return FindRevisionWorkViews(data, hl.id).Select(w => RevisionWorkToDict(data, l, w)).ToList(); }
private LaneTreeNode BuildTree (FrontPageResponse data) { LaneTreeNode result = LaneTreeNode.BuildTree (data.Lanes, data.HostLanes); if (data.Lane != null) { result = result.Find (v => v.Lane != null && v.Lane.id == data.Lane.id); } else if (data.SelectedLanes.Count > 1) { for (int i = result.Children.Count - 1; i >= 0; i--) { LaneTreeNode ltn = result.Children [i]; if (!data.SelectedLanes.Exists ((DBLane l) => l.id == ltn.Lane.id)) { result.Children.RemoveAt (i); } } } return result; }
public string GenerateOverview (FrontPageResponse data) { StringBuilder matrix = new StringBuilder (); LaneTreeNode tree = BuildTree (data); List<StringBuilder> header_rows = new List<StringBuilder> (); List<int> hostlane_order = new List<int> (); if (tree == null) return string.Empty; // This renders all the host header lanes WriteLanes (header_rows, tree, 0, tree.Depth); matrix.AppendLine ("<table class='buildstatus'>"); for (int i = 0; i < header_rows.Count; i++) { if (header_rows [i].Length == 0) continue; matrix.Append ("<tr>"); matrix.Append (header_rows [i]); matrix.AppendLine ("</tr>"); } // Renders all the hosts matrix.AppendLine ("<tr>"); WriteHostLanes (matrix, tree, data.Hosts, hostlane_order); matrix.AppendLine ("</tr>"); // Renders all the builds int counter = 0; int added = 0; StringBuilder row = new StringBuilder (); do { added = 0; row.Length = 0; for (int i = 0; i < hostlane_order.Count; i++) { int hl_id = hostlane_order [i]; var rev = FindRevisionWorkViews (data, hl_id); DBRevisionWorkView2 work = null; if (rev != null && rev.Count > counter) { work = rev [counter]; added++; } WriteWorkCell (row, work); } if (added > 0 && row.Length > 0) { matrix.Append ("<tr>"); matrix.Append (row.ToString ()); matrix.Append ("</tr>"); } counter++; } while (counter <= limit && added > 0); matrix.AppendLine ("</table>"); return matrix.ToString (); }
public string GenerateTaggedOverview (FrontPageResponse data) { StringBuilder matrix = new StringBuilder (); var lane_row = new StringBuilder (); var hl_row = new StringBuilder (); var rows = new List<StringBuilder> (); // First pass to get the total ammount of rows needed. for (int i = 0; i < data.SelectedLanes.Count; i++) { var lane = data.SelectedLanes [i]; var hls = data.HostLanes.FindAll ((hl) => hl.lane_id == lane.id); foreach (var hl in hls) { var work_views = FindRevisionWorkViews (data, hl.id); // Create more rows if needed. if (rows.Count < work_views.Count) { rows.Capacity = work_views.Count; for (int r = rows.Count; r < work_views.Count; r++) rows.Add (new StringBuilder ()); } } } // Render pass matrix.AppendLine ("<table class='buildstatus'>"); for (int i = 0; i < data.SelectedLanes.Count; i++) { var lane = data.SelectedLanes [i]; var hls = data.HostLanes.FindAll ((hl) => hl.lane_id == lane.id); lane_row.AppendFormat ("<td colspan='{1}'>{0}</td>", data.SelectedLanes [i].lane, hls.Count == 0 ? 1 : hls.Count).AppendLine (); foreach (var hl in hls) { // This renders all the host header lanes WriteHostLane (hl_row, data.Hosts, hl); // Find all the builds var work_views = FindRevisionWorkViews (data, hl.id); // Create more rows if needed. if (rows.Count < work_views.Count) { rows.Capacity = work_views.Count; for (int r = rows.Count; r < work_views.Count; r++) rows.Add (new StringBuilder ()); } for (int r = 0; r < work_views.Count; r++) { WriteWorkCell (rows [r], work_views [r]); } // Fix the staggering, add the empty cells. if (work_views.Count < rows.Count) for (int r = work_views.Count; r < rows.Count; r++) { WriteWorkCell (rows [r], null); } } } matrix.Append ("<tr>").Append (lane_row).AppendLine ("</tr>"); matrix.Append ("<tr>").Append (hl_row).AppendLine ("</tr>"); for (int r = 0; r < rows.Count; r++) { matrix.Append ("<tr>").Append (rows [r]).AppendLine ("</tr>"); } matrix.AppendLine ("</table>"); return matrix.ToString (); }
public FrontPageResponse GetFrontPageData2 (WebServiceLogin login, int limit, string [] lanes, int [] lane_ids) { FrontPageResponse response = new FrontPageResponse (); List<DBLane> Lanes = new List<DBLane> (); List<DBHost> Hosts = new List<DBHost> (); List<DBHostLane> HostLanes = new List<DBHostLane> (); List<DBRevisionWorkView2> RevisionWork; limit = Math.Min (limit, 500); using (DB db = new DB ()) { Authenticate (db, login, response, true); using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = DBLane.TableName; cmd.CommandType = CommandType.TableDirect; using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) Lanes.Add (new DBLane (reader)); } } using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = DBHost.TableName; cmd.CommandType = CommandType.TableDirect; using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) Hosts.Add (new DBHost (reader)); } } // get a list of the lanes to show // note that the logic here is slightly different from the usual "string lane, int? lane_id" logic in other methods, // where we only use the string parameter if the id parameter isn't provided, here we add everything we can to the // list of selected lanes, so if you provide both a string and an id parameter both are used (assuming they correspond // with different lanes of course). response.SelectedLanes = Lanes.FindAll (delegate (DBLane l) { if (lane_ids != null) { for (int i = 0; i < lane_ids.Length; i++) { if (lane_ids [i] == l.id) return true; } } if (lanes != null) { for (int i = 0; i < lanes.Length; i++) { if (!string.IsNullOrEmpty (lanes [i]) && lanes [i] == l.lane) return true; } } return false; }); // backwards compat if (response.SelectedLanes.Count == 1) response.Lane = response.SelectedLanes [0]; using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = @" SELECT HostLane.* FROM HostLane"; using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) HostLanes.Add (new DBHostLane (reader)); } } response.RevisionWorkViews = new List<List<DBRevisionWorkView2>> (); response.RevisionWorkHostLaneRelation = new List<int> (); foreach (DBHostLane hl in HostLanes) { RevisionWork = new List<DBRevisionWorkView2> (); using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = @"SELECT R.* FROM (" + DBRevisionWorkView2.SQL.Replace (';', ' ') + ") AS R WHERE R.host_id = @host_id AND R.lane_id = @lane_id LIMIT @limit"; DB.CreateParameter (cmd, "host_id", hl.host_id); DB.CreateParameter (cmd, "lane_id", hl.lane_id); DB.CreateParameter (cmd, "limit", limit); using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) RevisionWork.Add (new DBRevisionWorkView2 (reader)); } } response.RevisionWorkHostLaneRelation.Add (hl.id); response.RevisionWorkViews.Add (RevisionWork); } response.Lanes = Lanes; response.Hosts = Hosts; response.HostLanes = HostLanes; return response; } }
public FrontPageResponse GetFrontPageData3 (WebServiceLogin login, int page_size, int page, string [] lanes, int [] lane_ids) { FrontPageResponse response = new FrontPageResponse (); List<DBLane> Lanes = new List<DBLane> (); List<DBHost> Hosts = new List<DBHost> (); List<DBHostLane> HostLanes = new List<DBHostLane> (); List<DBRevisionWorkView2> RevisionWork; page_size = Math.Min (page_size, 500); try { using (DB db = new DB ()) { Authenticate (db, login, response, true); using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = DBLane.TableName; cmd.CommandType = CommandType.TableDirect; using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) Lanes.Add (new DBLane (reader)); } } using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = DBHost.TableName; cmd.CommandType = CommandType.TableDirect; using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) Hosts.Add (new DBHost (reader)); } } // get a list of the lanes to show // note that the logic here is slightly different from the usual "string lane, int? lane_id" logic in other methods, // where we only use the string parameter if the id parameter isn't provided, here we add everything we can to the // list of selected lanes, so if you provide both a string and an id parameter both are used (assuming they correspond // with different lanes of course). response.SelectedLanes = Lanes.FindAll (delegate (DBLane l) { if (lane_ids != null) { for (int i = 0; i < lane_ids.Length; i++) { if (lane_ids [i] == l.id) return true; } } if (lanes != null) { for (int i = 0; i < lanes.Length; i++) { if (!string.IsNullOrEmpty (lanes [i]) && lanes [i] == l.lane) return true; } } return false; }); // backwards compat if (response.SelectedLanes.Count == 1) response.Lane = response.SelectedLanes [0]; using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = @" SELECT HostLane.* FROM HostLane WHERE hidden = false"; using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) HostLanes.Add (new DBHostLane (reader)); } } response.RevisionWorkViews = new List<List<DBRevisionWorkView2>> (); response.RevisionWorkHostLaneRelation = new List<int> (); foreach (DBHostLane hl in HostLanes) { RevisionWork = new List<DBRevisionWorkView2> (); using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = @"SELECT R.* FROM (" + DBRevisionWorkView2.SQL.Replace (';', ' ') + ") AS R WHERE R.host_id = @host_id AND R.lane_id = @lane_id LIMIT @limit OFFSET @offset"; DB.CreateParameter (cmd, "host_id", hl.host_id); DB.CreateParameter (cmd, "lane_id", hl.lane_id); DB.CreateParameter (cmd, "limit", page_size); DB.CreateParameter (cmd, "offset", page * page_size); using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) RevisionWork.Add (new DBRevisionWorkView2 (reader)); } } response.RevisionWorkHostLaneRelation.Add (hl.id); response.RevisionWorkViews.Add (RevisionWork); } // Create a list of all the lanes which have hostlanes var enabled_set = new HashSet<int> (); foreach (DBHostLane hl in HostLanes) { if (enabled_set.Contains (hl.lane_id)) continue; enabled_set.Add (hl.lane_id); // Walk up the tree of parent lanes, marking all the parents too var l = Lanes.First ((v) => v.id == hl.lane_id); while (true) { if (!l.parent_lane_id.HasValue) break; if (enabled_set.Contains (l.parent_lane_id.Value)) break; enabled_set.Add (l.parent_lane_id.Value); l = Lanes.First ((v) => v.id == l.parent_lane_id.Value); } } // Remove the lanes which aren't marked for (int i = Lanes.Count - 1; i >= 0; i--) { if (!enabled_set.Contains (Lanes [i].id)) { Lanes.RemoveAt (i); } } response.Lanes = Lanes; response.Hosts = Hosts; response.HostLanes = HostLanes; } } catch (Exception ex) { response.Exception = new WebServiceException (ex); } return response; }