Create and use Reachable primitive

This commit is contained in:
Joscha 2024-05-13 16:04:02 +02:00
parent 5a4784be56
commit 7d80ba4a6b
24 changed files with 136 additions and 87 deletions

View file

@ -22,6 +22,15 @@ pub enum Direction {
MoreIsBetter = 1,
}
/// How a commit can be reached from refs.
#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, sqlx::Type)]
#[repr(u8)]
pub enum Reachable {
Unreachable = 0,
FromAnyRef = 1,
FromTrackedRef = 2,
}
/// A time stamp, usually formatted using RFC3339.
#[derive(Clone, Copy, sqlx::Type)]
#[sqlx(transparent)]

View file

@ -2,16 +2,19 @@ use log::{debug, info, warn};
use sqlx::{Acquire, SqlitePool};
use time::OffsetDateTime;
use crate::somehow;
use crate::{primitive::Reachable, somehow};
async fn inner(db: &SqlitePool) -> somehow::Result<()> {
let mut tx = db.begin().await?;
let conn = tx.acquire().await?;
// Get all newly added tracked commits
let new = sqlx::query!("SELECT hash FROM commits WHERE new AND reachable = 2")
.fetch_all(&mut *conn)
.await?;
let new = sqlx::query!(
"SELECT hash FROM commits WHERE new AND reachable = ?",
Reachable::FromTrackedRef,
)
.fetch_all(&mut *conn)
.await?;
debug!("Found {} new commits", new.len());
// Insert them into the queue
@ -38,13 +41,17 @@ async fn inner(db: &SqlitePool) -> somehow::Result<()> {
//
// When tracked refs are updated, all new commits are automatically added to
// the queue, since they were still new and have now transitioned to
// reachable = 2. This should hopefully not be too big of a problem since
// usually the main branch is also tracked. I think I'd rather implement
// better queue management tools and graph UI than change this behaviour.
let amount = sqlx::query!("UPDATE commits SET new = false WHERE reachable = 2")
.execute(&mut *conn)
.await?
.rows_affected();
// Reachable::FromTrackedRef. This should hopefully not be too big of a
// problem since usually the main branch is also tracked. I think I'd rather
// implement better queue management tools and graph UI than change this
// behaviour.
let amount = sqlx::query!(
"UPDATE commits SET new = false WHERE reachable = ?",
Reachable::FromTrackedRef,
)
.execute(&mut *conn)
.await?
.rows_affected();
debug!("Marked {amount} commits as old");
tx.commit().await?;

View file

@ -9,6 +9,7 @@ use sqlx::{Acquire, SqliteConnection, SqlitePool};
use time::{OffsetDateTime, UtcOffset};
use crate::{
primitive::Reachable,
server::{format, Repo},
somehow,
};
@ -227,11 +228,14 @@ async fn update_commit_tracked_status(conn: &mut SqliteConnection) -> somehow::R
) \
UPDATE commits \
SET reachable = CASE \
WHEN hash IN tracked THEN 2 \
WHEN hash IN reachable THEN 1 \
ELSE 0 \
WHEN hash IN tracked THEN ? \
WHEN hash IN reachable THEN ? \
ELSE ? \
END \
"
",
Reachable::FromTrackedRef,
Reachable::FromAnyRef,
Reachable::Unreachable,
)
.execute(conn)
.await?;

View file

@ -10,6 +10,7 @@ use time::OffsetDateTime;
use crate::{
config::ServerConfig,
primitive::Reachable,
server::web::{
paths::{
PathAdminQueueAdd, PathAdminQueueAddBatch, PathAdminQueueDecrease,
@ -75,12 +76,13 @@ pub async fn post_admin_queue_add_batch(
SELECT hash, ?, ? \
FROM commits \
LEFT JOIN runs USING (hash) \
WHERE reachable = 2 AND id IS NULL \
WHERE reachable = ? AND id IS NULL \
ORDER BY unixepoch(committer_date) DESC \
LIMIT ? \
",
date,
form.priority,
Reachable::FromTrackedRef,
form.amount,
)
.execute(&db)

View file

@ -1,7 +1,7 @@
use maud::{html, Markup};
use time::OffsetDateTime;
use crate::{config::ServerConfig, server::format};
use crate::{config::ServerConfig, primitive::Reachable, server::format};
use super::{
paths::{PathCommitByHash, PathRunById, PathWorkerByName},
@ -17,26 +17,29 @@ pub fn join(sections: &[Markup], with: Markup) -> Markup {
}
}
pub fn commit_class_and_title(reachable: i64) -> (&'static str, &'static str) {
if reachable == 0 {
(
pub fn commit_class_and_title(reachable: Reachable) -> (&'static str, &'static str) {
match reachable {
Reachable::Unreachable => (
"commit-orphaned",
"This commit is orphaned. It can't be reached from any ref.",
)
} else if reachable == -1 {
(
),
Reachable::FromAnyRef => (
"commit-reachable",
"This commit can only be reached from untracked refs.",
)
} else {
(
),
Reachable::FromTrackedRef => (
"commit-tracked",
"This commit can be reached from a tracked ref.",
)
),
}
}
pub fn link_commit(config: &ServerConfig, hash: String, message: &str, reachable: i64) -> Markup {
pub fn link_commit(
config: &ServerConfig,
hash: String,
message: &str,
reachable: Reachable,
) -> Markup {
let short = format::truncate(&format::commit_short(&hash, message), 80);
let path = config.path(PathCommitByHash { hash });
let (class, title) = commit_class_and_title(reachable);

View file

@ -9,6 +9,7 @@ use sqlx::SqlitePool;
use crate::{
config::ServerConfig,
primitive::Reachable,
server::{
format,
web::{
@ -35,7 +36,7 @@ pub async fn get_commit_by_hash(
committer, \
committer_date AS \"committer_date: time::OffsetDateTime\", \
message, \
reachable \
reachable AS \"reachable: Reachable\" \
FROM commits \
WHERE hash = ? \
",
@ -49,7 +50,11 @@ pub async fn get_commit_by_hash(
let parents = sqlx::query!(
"\
SELECT hash, message, reachable FROM commits \
SELECT \
hash, \
message, \
reachable AS \"reachable: Reachable\" \
FROM commits \
JOIN commit_edges ON hash = parent \
WHERE child = ? \
ORDER BY reachable DESC, unixepoch(committer_date) ASC \
@ -63,7 +68,11 @@ pub async fn get_commit_by_hash(
let children = sqlx::query!(
"\
SELECT hash, message, reachable FROM commits \
SELECT \
hash, \
message, \
reachable AS \"reachable: Reachable\" \
FROM commits \
JOIN commit_edges ON hash = child \
WHERE parent = ? \
ORDER BY reachable DESC, unixepoch(committer_date) ASC \

View file

@ -10,6 +10,7 @@ use time::OffsetDateTime;
use crate::{
config::ServerConfig,
primitive::Reachable,
server::{
format,
web::{
@ -99,9 +100,10 @@ pub async fn get_graph_commits(
message, \
committer_date AS \"committer_date: OffsetDateTime\" \
FROM commits \
WHERE reachable = 2 \
WHERE reachable = ? \
ORDER BY hash ASC \
"
",
Reachable::FromTrackedRef,
)
.fetch(&mut *conn);
while let Some(row) = rows.try_next().await? {
@ -126,9 +128,10 @@ pub async fn get_graph_commits(
SELECT child, parent \
FROM commit_edges \
JOIN commits ON hash = child \
WHERE reachable = 2 \
WHERE reachable = ? \
ORDER BY hash ASC \
"
",
Reachable::FromTrackedRef,
)
.fetch(&mut *conn);
while let Some(row) = rows.try_next().await? {

View file

@ -5,6 +5,7 @@ use sqlx::SqlitePool;
use crate::{
config::ServerConfig,
primitive::Reachable,
server::web::{
components,
page::{Page, Tab},
@ -27,7 +28,12 @@ pub async fn get_index(
) -> somehow::Result<impl IntoResponse> {
let refs = sqlx::query!(
"\
SELECT name, hash, message, reachable, tracked \
SELECT \
name, \
hash, \
message, \
reachable AS \"reachable: Reachable\", \
tracked \
FROM refs \
JOIN commits USING (hash) \
ORDER BY name ASC \

View file

@ -14,6 +14,7 @@ use sqlx::SqlitePool;
use crate::{
config::ServerConfig,
primitive::Reachable,
server::{
format,
web::{
@ -120,7 +121,7 @@ async fn get_queue_data(
SELECT \
hash, \
message, \
reachable, \
reachable AS \"reachable: Reachable\", \
date AS \"date: time::OffsetDateTime\", \
priority \
FROM queue \
@ -276,7 +277,11 @@ pub async fn get_queue_delete(
) -> somehow::Result<Response> {
let Some(r) = sqlx::query!(
"\
SELECT hash, message, reachable FROM commits \
SELECT \
hash, \
message, \
reachable AS \"reachable: Reachable\" \
FROM commits \
JOIN queue USING (hash) \
WHERE hash = ? \
",

View file

@ -9,6 +9,7 @@ use sqlx::SqlitePool;
use crate::{
config::ServerConfig,
primitive::Reachable,
server::{
format,
web::{components, page::Page, paths::PathRunById},
@ -42,7 +43,7 @@ async fn from_finished_run(
end AS \"end: time::OffsetDateTime\", \
exit_code, \
message, \
reachable \
reachable AS \"reachable: Reachable\" \
FROM runs \
JOIN commits USING (hash) \
WHERE id = ? \