Changeset 390 for trunk/sources/HeuristicLab.CEDMA.DB
- Timestamp:
- 07/22/08 19:15:29 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.CEDMA.DB/Database.cs
r389 r390 55 55 } 56 56 using(DbCommand cmd = cnn.CreateCommand()) { 57 cmd.CommandText = "CREATE TABLE Agent (ID integer primary key autoincrement, ProjectId integer, Name text, Status text default 'Unknown', RawData Blob)";57 cmd.CommandText = "CREATE TABLE Agent (ID integer primary key autoincrement, ProjectId integer, ParentAgentId integer, Name text, Status text default 'Unknown', ControllerAgent integer, RawData Blob)"; 58 58 cmd.Transaction = t; 59 59 cmd.ExecuteNonQuery(); 60 60 } 61 61 using(DbCommand cmd = cnn.CreateCommand()) { 62 cmd.CommandText = "CREATE TABLE R un (ID integer primary key autoincrement, AgentId integer, CreationTime DateTime, StartTime DateTime, FinishedTime DateTime, Status text default 'Unknown', RawData Blob)";62 cmd.CommandText = "CREATE TABLE Result (ID integer primary key autoincrement, AgentId integer, ParentResultId integer, Summary text, Description text, CreationTime DateTime, RawData Blob)"; 63 63 cmd.Transaction = t; 64 64 cmd.ExecuteNonQuery(); 65 65 } 66 using(DbCommand cmd = cnn.CreateCommand()) {67 cmd.CommandText = "CREATE TABLE Result (ID integer primary key autoincrement, RunId integer, ResultId integer, CreationTime DateTime, RawData Blob)";68 cmd.Transaction = t;69 cmd.ExecuteNonQuery();70 }71 66 t.Commit(); 72 67 } … … 79 74 80 75 #region insert agent/run/result/sub-result 81 public long InsertAgent( string name, byte[] rawData) {76 public long InsertAgent(long? parentAgentId, string name, bool controllerAgent, byte[] rawData) { 82 77 rwLock.EnterWriteLock(); 83 78 try { … … 88 83 using(DbCommand c = cnn.CreateCommand()) { 89 84 c.Transaction = t; 90 c.CommandText = "Insert into Agent (Name, RawData) values (@Name, @RawData); select last_insert_rowid()";85 c.CommandText = "Insert into Agent (Name, ParentAgentId, ControllerAgent, RawData) values (@Name, @ParentAgentId, @ControllerAgent, @RawData); select last_insert_rowid()"; 91 86 DbParameter nameParam = c.CreateParameter(); 92 87 nameParam.ParameterName = "@Name"; 93 88 nameParam.Value = name; 94 89 c.Parameters.Add(nameParam); 90 DbParameter parentParam = c.CreateParameter(); 91 parentParam.ParameterName = "@ParentAgentId"; 92 parentParam.Value = parentAgentId; 93 c.Parameters.Add(parentParam); 94 DbParameter controllerParam = c.CreateParameter(); 95 controllerParam.ParameterName = "@ControllerAgent"; 96 controllerParam.Value = controllerAgent; 97 c.Parameters.Add(controllerParam); 95 98 DbParameter dataParam = c.CreateParameter(); 96 99 dataParam.ParameterName = "@RawData"; … … 108 111 } 109 112 110 public long InsertR un(long agentId, byte[] rawData) {113 public long InsertResult(long agentId, string summary, string description, byte[] rawData) { 111 114 rwLock.EnterWriteLock(); 112 115 try { … … 117 120 using(DbCommand c = cnn.CreateCommand()) { 118 121 c.Transaction = t; 119 c.CommandText = "Insert into R un (AgentId, CreationTime, RawData) values (@AgentId, @CreationTime, @RawData); select last_insert_rowid()";122 c.CommandText = "Insert into Result (AgentId, CreationTime, Summary, Description, RawData) values (@AgentId, @CreationTime, @Summary, @Description, @RawData); select last_insert_rowid()"; 120 123 DbParameter agentIdParam = c.CreateParameter(); 121 124 agentIdParam.ParameterName = "@AgentId"; … … 127 130 creationParam.Value = now; 128 131 c.Parameters.Add(creationParam); 132 DbParameter summaryParam = c.CreateParameter(); 133 summaryParam.ParameterName = "@Summary"; 134 summaryParam.Value = summary; 135 c.Parameters.Add(summaryParam); 136 DbParameter descParam = c.CreateParameter(); 137 descParam.ParameterName = "@Description"; 138 descParam.Value = description; 139 c.Parameters.Add(descParam); 129 140 DbParameter rawDataParam = c.CreateParameter(); 130 141 rawDataParam.ParameterName = "@RawData"; … … 142 153 } 143 154 144 public long Insert Result(long runId, byte[] rawData) {155 public long InsertSubResult(long resultId, string summary, string description, byte[] rawData) { 145 156 rwLock.EnterWriteLock(); 146 157 try { … … 151 162 using(DbCommand c = cnn.CreateCommand()) { 152 163 c.Transaction = t; 153 c.CommandText = "Insert into Result (RunId, CreationTime, RawData) values (@RunId, @CreationTime, @RawData); select last_insert_rowid()"; 154 DbParameter runIdParam = c.CreateParameter(); 155 runIdParam.ParameterName = "@RunId"; 156 runIdParam.Value = runId; 157 c.Parameters.Add(runIdParam); 158 DbParameter creationParam = c.CreateParameter(); 159 creationParam.ParameterName = "@CreationTime"; 160 DateTime now = DateTime.Now; 161 creationParam.Value = now; 162 c.Parameters.Add(creationParam); 163 DbParameter rawDataParam = c.CreateParameter(); 164 rawDataParam.ParameterName = "@RawData"; 165 rawDataParam.Value = rawData; 166 c.Parameters.Add(rawDataParam); 167 id = (long)c.ExecuteScalar(); 168 } 169 t.Commit(); 170 return id; 171 } 172 } 173 } finally { 174 rwLock.ExitWriteLock(); 175 } 176 } 177 178 public long InsertSubResult(long resultId, byte[] rawData) { 179 rwLock.EnterWriteLock(); 180 try { 181 using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) { 182 cnn.Open(); 183 long id; 184 using(DbTransaction t = cnn.BeginTransaction()) { 185 using(DbCommand c = cnn.CreateCommand()) { 186 c.Transaction = t; 187 c.CommandText = "Insert into Result (ResultId, CreationTime, RawData) values (@ResultId, @CreationTime, @RawData); select last_insert_rowid()"; 164 c.CommandText = "Insert into Result (ParentResultId, CreationTime, Summary, Description, RawData) values (@ParentResultId, @CreationTime, @Summary, @Description, @RawData); select last_insert_rowid()"; 188 165 DbParameter resultIdParam = c.CreateParameter(); 189 resultIdParam.ParameterName = "@ ResultId";166 resultIdParam.ParameterName = "@ParentResultId"; 190 167 resultIdParam.Value = resultId; 191 168 c.Parameters.Add(resultIdParam); … … 195 172 creationParam.Value = now; 196 173 c.Parameters.Add(creationParam); 174 DbParameter summaryParam = c.CreateParameter(); 175 summaryParam.ParameterName = "@Summary"; 176 summaryParam.Value = summary; 177 c.Parameters.Add(summaryParam); 178 DbParameter descParam = c.CreateParameter(); 179 descParam.ParameterName = "@Description"; 180 descParam.Value = description; 181 c.Parameters.Add(descParam); 197 182 DbParameter rawDataParam = c.CreateParameter(); 198 183 rawDataParam.ParameterName = "@RawData"; … … 293 278 } 294 279 295 public void UpdateRunStart(long runId, DateTime startTime) {296 rwLock.EnterWriteLock();297 try {298 using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {299 cnn.Open();300 using(SQLiteTransaction t = cnn.BeginTransaction()) {301 using(SQLiteCommand c = cnn.CreateCommand()) {302 c.Transaction = t;303 c.CommandText = "Update Run set StartTime=@StartTime where id=@Id";304 DbParameter startTimeParam = c.CreateParameter();305 DbParameter idParam = c.CreateParameter();306 startTimeParam.ParameterName = "@StartTime";307 startTimeParam.Value = startTime;308 idParam.ParameterName = "@Id";309 idParam.Value = runId;310 c.Parameters.Add(startTimeParam);311 c.Parameters.Add(idParam);312 c.ExecuteNonQuery();313 }314 t.Commit();315 }316 }317 } finally {318 rwLock.ExitWriteLock();319 }320 }321 322 public void UpdateRunFinished(long runId, DateTime finishedTime) {323 rwLock.EnterWriteLock();324 try {325 using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {326 cnn.Open();327 using(SQLiteTransaction t = cnn.BeginTransaction()) {328 using(SQLiteCommand c = cnn.CreateCommand()) {329 c.Transaction = t;330 c.CommandText = "Update Run set FinishedTime=@FinishedTime where id=@Id";331 DbParameter finishedTimeParam = c.CreateParameter();332 DbParameter idParam = c.CreateParameter();333 finishedTimeParam.ParameterName = "@FinishedTime";334 finishedTimeParam.Value = finishedTime;335 idParam.ParameterName = "@Id";336 idParam.Value = runId;337 c.Parameters.Add(finishedTimeParam);338 c.Parameters.Add(idParam);339 c.ExecuteNonQuery();340 }341 t.Commit();342 }343 }344 } finally {345 rwLock.ExitWriteLock();346 }347 }348 349 public void UpdateRunStatus(long runId, ProcessStatus status) {350 rwLock.EnterWriteLock();351 try {352 using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {353 cnn.Open();354 using(SQLiteTransaction t = cnn.BeginTransaction()) {355 using(SQLiteCommand c = cnn.CreateCommand()) {356 c.Transaction = t;357 c.CommandText = "Update Run set Status=@Status where id=@Id";358 DbParameter statusParam = c.CreateParameter();359 DbParameter idParam = c.CreateParameter();360 statusParam.ParameterName = "@Status";361 statusParam.Value = status;362 idParam.ParameterName = "@Id";363 idParam.Value = runId;364 c.Parameters.Add(statusParam);365 c.Parameters.Add(idParam);366 c.ExecuteNonQuery();367 }368 t.Commit();369 }370 }371 } finally {372 rwLock.ExitWriteLock();373 }374 }280 //public void UpdateRunStart(long runId, DateTime startTime) { 281 // rwLock.EnterWriteLock(); 282 // try { 283 // using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) { 284 // cnn.Open(); 285 // using(SQLiteTransaction t = cnn.BeginTransaction()) { 286 // using(SQLiteCommand c = cnn.CreateCommand()) { 287 // c.Transaction = t; 288 // c.CommandText = "Update Run set StartTime=@StartTime where id=@Id"; 289 // DbParameter startTimeParam = c.CreateParameter(); 290 // DbParameter idParam = c.CreateParameter(); 291 // startTimeParam.ParameterName = "@StartTime"; 292 // startTimeParam.Value = startTime; 293 // idParam.ParameterName = "@Id"; 294 // idParam.Value = runId; 295 // c.Parameters.Add(startTimeParam); 296 // c.Parameters.Add(idParam); 297 // c.ExecuteNonQuery(); 298 // } 299 // t.Commit(); 300 // } 301 // } 302 // } finally { 303 // rwLock.ExitWriteLock(); 304 // } 305 //} 306 307 //public void UpdateRunFinished(long runId, DateTime finishedTime) { 308 // rwLock.EnterWriteLock(); 309 // try { 310 // using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) { 311 // cnn.Open(); 312 // using(SQLiteTransaction t = cnn.BeginTransaction()) { 313 // using(SQLiteCommand c = cnn.CreateCommand()) { 314 // c.Transaction = t; 315 // c.CommandText = "Update Run set FinishedTime=@FinishedTime where id=@Id"; 316 // DbParameter finishedTimeParam = c.CreateParameter(); 317 // DbParameter idParam = c.CreateParameter(); 318 // finishedTimeParam.ParameterName = "@FinishedTime"; 319 // finishedTimeParam.Value = finishedTime; 320 // idParam.ParameterName = "@Id"; 321 // idParam.Value = runId; 322 // c.Parameters.Add(finishedTimeParam); 323 // c.Parameters.Add(idParam); 324 // c.ExecuteNonQuery(); 325 // } 326 // t.Commit(); 327 // } 328 // } 329 // } finally { 330 // rwLock.ExitWriteLock(); 331 // } 332 //} 333 334 //public void UpdateRunStatus(long runId, ProcessStatus status) { 335 // rwLock.EnterWriteLock(); 336 // try { 337 // using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) { 338 // cnn.Open(); 339 // using(SQLiteTransaction t = cnn.BeginTransaction()) { 340 // using(SQLiteCommand c = cnn.CreateCommand()) { 341 // c.Transaction = t; 342 // c.CommandText = "Update Run set Status=@Status where id=@Id"; 343 // DbParameter statusParam = c.CreateParameter(); 344 // DbParameter idParam = c.CreateParameter(); 345 // statusParam.ParameterName = "@Status"; 346 // statusParam.Value = status; 347 // idParam.ParameterName = "@Id"; 348 // idParam.Value = runId; 349 // c.Parameters.Add(statusParam); 350 // c.Parameters.Add(idParam); 351 // c.ExecuteNonQuery(); 352 // } 353 // t.Commit(); 354 // } 355 // } 356 // } finally { 357 // rwLock.ExitWriteLock(); 358 // } 359 //} 375 360 #endregion 376 361 … … 384 369 cnn.Open(); 385 370 SQLiteCommand c = cnn.CreateCommand(); 386 c.CommandText = "Select id, name, status, rawdata from Agent where Status=@Status";371 c.CommandText = "Select id, name, ControllerAgent, rawdata from Agent where Status=@Status"; 387 372 DbParameter statusParameter = c.CreateParameter(); 388 373 statusParameter.ParameterName = "@Status"; … … 393 378 while(r.Read()) { 394 379 AgentEntry agent = new AgentEntry(); 380 agent.ParentAgentId = null; 381 agent.Status = status; 395 382 agent.Id = r.GetInt32(0); 396 agent.Name = r. GetString(1);397 agent. Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(2));383 agent.Name = r.IsDBNull(1)?"":r.GetString(1); 384 agent.ControllerAgent = r.GetBoolean(2); 398 385 agent.RawData = (byte[])r.GetValue(3); 399 386 agents.Add(agent); … … 413 400 cnn.Open(); 414 401 using(DbCommand c = cnn.CreateCommand()) { 415 c.CommandText = "Select id, name, status, rawdata from Agent";402 c.CommandText = "Select id, ParentAgentId, name, status, ControllerAgent, rawdata from Agent"; 416 403 using(DbDataReader r = c.ExecuteReader()) { 417 404 while(r.Read()) { 418 405 AgentEntry agent = new AgentEntry(); 419 406 agent.Id = r.GetInt32(0); 407 agent.ParentAgentId = r.IsDBNull(1) ? null : new Nullable<long>(r.GetInt32(1)); 408 agent.Name = r.GetString(2); 409 agent.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3)); 410 agent.ControllerAgent = r.GetBoolean(4); 411 agent.RawData = (byte[])r.GetValue(5); 412 agents.Add(agent); 413 } 414 } 415 } 416 } 417 } finally { 418 rwLock.ExitReadLock(); 419 } 420 return agents; 421 } 422 423 public ICollection<AgentEntry> GetSubAgents(long parentAgentId) { 424 rwLock.EnterReadLock(); 425 List<AgentEntry> agents = new List<AgentEntry>(); 426 try { 427 using(DbConnection cnn = new SQLiteConnection(connectionString)) { 428 cnn.Open(); 429 using(DbCommand c = cnn.CreateCommand()) { 430 c.CommandText = "Select id, name, status, controllerAgent, rawdata from Agent where ParentAgentId=@ParentAgentId"; 431 using(DbDataReader r = c.ExecuteReader()) { 432 while(r.Read()) { 433 AgentEntry agent = new AgentEntry(); 434 agent.ParentAgentId = parentAgentId; 435 agent.Id = r.GetInt32(0); 420 436 agent.Name = r.GetString(1); 421 437 agent.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(2)); 422 agent.RawData = (byte[])r.GetValue(3); 438 agent.ControllerAgent = r.GetBoolean(3); 439 agent.RawData = (byte[])r.GetValue(4); 423 440 agents.Add(agent); 424 441 } … … 432 449 } 433 450 434 public ICollection<RunEntry> GetRuns(long agentId) {435 List<RunEntry> runs = new List<RunEntry>();436 rwLock.EnterReadLock();437 try {438 using(DbConnection cnn = new SQLiteConnection(connectionString)) {439 cnn.Open();440 using(DbCommand c = cnn.CreateCommand()) {441 c.CommandText = "Select Id, AgentId, CreationTime, Status, Rawdata from Run where AgentId=@AgentId";442 DbParameter agentParameter = c.CreateParameter();443 agentParameter.ParameterName = "@AgentId";444 agentParameter.Value = agentId;445 c.Parameters.Add(agentParameter);446 447 using(DbDataReader r = c.ExecuteReader()) {448 while(r.Read()) {449 RunEntry run = new RunEntry();450 run.Id = r.GetInt32(0);451 run.AgentId = r.GetInt32(1);452 run.CreationTime = r.GetDateTime(2);453 run.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3));454 run.RawData = (byte[])r.GetValue(4);455 runs.Add(run);456 }457 }458 }459 }460 } finally {461 rwLock.ExitReadLock();462 }463 return runs;464 }465 466 public ICollection<RunEntry> GetRuns(ProcessStatus status) {467 List<RunEntry> runs = new List<RunEntry>();468 rwLock.EnterReadLock();469 try {470 using(DbConnection cnn = new SQLiteConnection(connectionString)) {471 cnn.Open();472 using(DbCommand c = cnn.CreateCommand()) {473 c.CommandText = "Select Id, AgentId, CreationTime, Status, Rawdata from Run where Status=@Status";474 DbParameter statusParameter = c.CreateParameter();475 statusParameter.ParameterName = "@Status";476 statusParameter.Value = status;477 c.Parameters.Add(statusParameter);478 479 using(DbDataReader r = c.ExecuteReader()) {480 while(r.Read()) {481 RunEntry run = new RunEntry();482 run.Id = r.GetInt32(0);483 run.AgentId = r.GetInt32(1);484 run.CreationTime = r.GetDateTime(2);485 run.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3));486 run.RawData = (byte[])r.GetValue(4);487 runs.Add(run);488 }489 }490 }491 }492 } finally {493 rwLock.ExitReadLock();494 }495 return runs;496 }497 498 public ICollection<ResultEntry> GetResults(long runId) {451 //public ICollection<RunEntry> GetRuns(long agentId) { 452 // List<RunEntry> runs = new List<RunEntry>(); 453 // rwLock.EnterReadLock(); 454 // try { 455 // using(DbConnection cnn = new SQLiteConnection(connectionString)) { 456 // cnn.Open(); 457 // using(DbCommand c = cnn.CreateCommand()) { 458 // c.CommandText = "Select Id, AgentId, CreationTime, Status, Rawdata from Run where AgentId=@AgentId"; 459 // DbParameter agentParameter = c.CreateParameter(); 460 // agentParameter.ParameterName = "@AgentId"; 461 // agentParameter.Value = agentId; 462 // c.Parameters.Add(agentParameter); 463 464 // using(DbDataReader r = c.ExecuteReader()) { 465 // while(r.Read()) { 466 // RunEntry run = new RunEntry(); 467 // run.Id = r.GetInt32(0); 468 // run.AgentId = r.GetInt32(1); 469 // run.CreationTime = r.GetDateTime(2); 470 // run.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3)); 471 // run.RawData = (byte[])r.GetValue(4); 472 // runs.Add(run); 473 // } 474 // } 475 // } 476 // } 477 // } finally { 478 // rwLock.ExitReadLock(); 479 // } 480 // return runs; 481 //} 482 483 //public ICollection<RunEntry> GetRuns(ProcessStatus status) { 484 // List<RunEntry> runs = new List<RunEntry>(); 485 // rwLock.EnterReadLock(); 486 // try { 487 // using(DbConnection cnn = new SQLiteConnection(connectionString)) { 488 // cnn.Open(); 489 // using(DbCommand c = cnn.CreateCommand()) { 490 // c.CommandText = "Select Id, AgentId, CreationTime, Status, Rawdata from Run where Status=@Status"; 491 // DbParameter statusParameter = c.CreateParameter(); 492 // statusParameter.ParameterName = "@Status"; 493 // statusParameter.Value = status; 494 // c.Parameters.Add(statusParameter); 495 496 // using(DbDataReader r = c.ExecuteReader()) { 497 // while(r.Read()) { 498 // RunEntry run = new RunEntry(); 499 // run.Id = r.GetInt32(0); 500 // run.AgentId = r.GetInt32(1); 501 // run.CreationTime = r.GetDateTime(2); 502 // run.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3)); 503 // run.RawData = (byte[])r.GetValue(4); 504 // runs.Add(run); 505 // } 506 // } 507 // } 508 // } 509 // } finally { 510 // rwLock.ExitReadLock(); 511 // } 512 // return runs; 513 //} 514 515 public ICollection<ResultEntry> GetResults(long agentId) { 499 516 List<ResultEntry> results = new List<ResultEntry>(); 500 517 rwLock.EnterReadLock(); … … 503 520 cnn.Open(); 504 521 using(DbCommand c = cnn.CreateCommand()) { 505 c.CommandText = "Select Id, RunId, CreationTime, Rawdata from Result"; 522 c.CommandText = "Select Id, CreationTime, Summary, Description, Rawdata from Result where AgentId=@AgentId"; 523 DbParameter agentParam = c.CreateParameter(); 524 agentParam.ParameterName = "@AgentId"; 525 agentParam.Value = agentId; 526 c.Parameters.Add(agentParam); 506 527 using(DbDataReader r = c.ExecuteReader()) { 507 528 while(r.Read()) { 508 529 ResultEntry result = new ResultEntry(); 530 result.AgentId = agentId; 509 531 result.Id = r.GetInt32(0); 510 result.RunId = r.GetInt32(1); 511 result.CreationTime = r.GetDateTime(2); 512 result.RawData = (byte[])r.GetValue(3); 532 result.CreationTime = r.GetDateTime(1); 533 result.Summary = r.GetString(2); 534 result.Description = r.GetString(3); 535 result.RawData = (byte[])r.GetValue(4); 513 536 results.Add(result); 514 537 } … … 523 546 524 547 public ICollection<ResultEntry> GetSubResults(long resultId) { 525 throw new NotImplementedException(); 548 List<ResultEntry> results = new List<ResultEntry>(); 549 rwLock.EnterReadLock(); 550 try { 551 using(DbConnection cnn = new SQLiteConnection(connectionString)) { 552 cnn.Open(); 553 using(DbCommand c = cnn.CreateCommand()) { 554 c.CommandText = "Select Id, CreationTime, Summary, Description, Rawdata from Result where ParentResultId=@ParentResultId"; 555 DbParameter parentParam = c.CreateParameter(); 556 parentParam.ParameterName = "@ParentResultId"; 557 parentParam.Value = resultId; 558 c.Parameters.Add(parentParam); 559 using(DbDataReader r = c.ExecuteReader()) { 560 while(r.Read()) { 561 ResultEntry result = new ResultEntry(); 562 result.ParentResultId = resultId; 563 result.Id = r.GetInt32(0); 564 result.CreationTime = r.GetDateTime(1); 565 result.Summary = r.GetString(2); 566 result.Description = r.GetString(3); 567 result.RawData = (byte[])r.GetValue(4); 568 results.Add(result); 569 } 570 } 571 } 572 } 573 } finally { 574 rwLock.ExitReadLock(); 575 } 576 return results; 526 577 } 527 578 #endregion
Note: See TracChangeset
for help on using the changeset viewer.