Skip to content

Commit

Permalink
provide all the meta-data that is needed to make a run (and associate…
Browse files Browse the repository at this point in the history
… it with that)
  • Loading branch information
Byron committed Jun 14, 2023
1 parent 83f6466 commit fcbda1d
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 11 deletions.
28 changes: 26 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion gitoxide-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ estimate-hours = ["dep:itertools", "dep:fs-err", "dep:crossbeam-channel", "dep:s
## Gather information about repositories and store it in a database for easy querying.
query = ["dep:rusqlite"]
## Run algorithms on a corpus of repositories and store their results for later comparison and intelligence gathering.
corpus = ["dep:rusqlite"]
corpus = ["dep:rusqlite", "dep:sysinfo"]

#! ### Mutually Exclusive Networking
#! If both are set, _blocking-client_ will take precedence, allowing `--all-features` to be used.
Expand Down Expand Up @@ -71,6 +71,9 @@ smallvec = { version = "1.10.0", optional = true }
# for 'query' and 'corpus'
rusqlite = { version = "0.29.0", optional = true, features = ["bundled"] }

# for 'corpus'
sysinfo = { version = "0.29.2", optional = true, default-features = false }

# for svg graph output
layout-rs = "0.1.1"
open = "4.1.0"
Expand Down
108 changes: 101 additions & 7 deletions gitoxide-core/src/corpus/mod.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,47 @@
pub struct Engine<P> {
progress: P,
con: rusqlite::Connection,
gitoxide_version: String,
}

pub mod engine {
use crate::corpus::Engine;
use anyhow::Context;
use std::path::PathBuf;

pub(crate) type Id = u32;

impl<P> Engine<P>
where
P: gix::Progress,
{
/// Open the corpus DB or create it.
pub fn open_or_create(db: PathBuf, progress: P) -> anyhow::Result<Engine<P>> {
pub fn open_or_create(db: PathBuf, gitoxide_version: String, progress: P) -> anyhow::Result<Engine<P>> {
let con = crate::corpus::db::create(db).context("Could not open or create database")?;
Ok(Engine { progress, con })
Ok(Engine {
progress,
con,
gitoxide_version,
})
}

/// Run on the existing set of repositories we have already seen or obtain them from `path` if there is none yet.
pub fn run(&self, _path: PathBuf) -> anyhow::Result<()> {
pub fn run(&self, path: PathBuf) -> anyhow::Result<()> {
let _corpus_id = self.corpus_id_or_insert(&path)?;
let _gitoxide_id = self.gitoxide_version_id_or_insert()?;
let _runner_id = self.runner_id_or_insert()?;
todo!()
}
}
}

pub mod db {
use anyhow::bail;
use crate::corpus::engine::Id;
use crate::corpus::Engine;
use anyhow::{bail, Context};
use rusqlite::{params, OptionalExtension};
use std::path::Path;
use sysinfo::{CpuExt, CpuRefreshKind, RefreshKind, SystemExt};

/// A version to be incremented whenever the database layout is changed, to refresh it automatically.
const VERSION: usize = 1;
Expand Down Expand Up @@ -81,7 +95,7 @@ pub mod db {
)?;
con.execute_batch(
r#"
CREATE TABLE if not exists gix_version(
CREATE TABLE if not exists gitoxide_version(
version text UNIQUE -- the unique git version via gix describe
)
"#,
Expand All @@ -91,17 +105,97 @@ pub mod db {
CREATE TABLE if not exists run(
repository integer,
runner integer,
gix_version integer,
gitoxide_version integer,
start_time integer,
end_time integer, -- or NULL if not yet finished (either successfull or with failure)
error text, -- or NULL if there was on error
FOREIGN KEY (repository) REFERENCES repository (rowid),
FOREIGN KEY (runner) REFERENCES runner (rowid),
FOREIGN KEY (gix_version) REFERENCES gix_version (rowid)
FOREIGN KEY (gitoxide_version) REFERENCES gitoxide_version (rowid)
)
"#,
)?;

Ok(con)
}

/// Utilities
impl<P> Engine<P> {
pub(crate) fn runner_id_or_insert(&self) -> anyhow::Result<Id> {
let sys = sysinfo::System::new_with_specifics(
RefreshKind::new().with_cpu(CpuRefreshKind::new().with_frequency()),
);
let cpu = &sys.cpus()[0];
let vendor = Some(cpu.vendor_id().to_owned());
let host = sys.host_name();
let brand = Some(cpu.brand().to_owned());
Ok(
match self
.con
.query_row(
"SELECT rowid FROM runner WHERE vendor = ?1 AND brand = ?2",
[vendor.as_deref(), brand.as_deref()],
|r| r.get(0),
)
.optional()?
{
Some(existing) => existing,
None => {
self.con.execute(
"INSERT INTO runner (vendor, brand, host_name) VALUES (?1, ?2, ?3)",
[vendor.as_deref(), brand.as_deref(), host.as_deref()],
)?;
self.con.query_row(
"SELECT rowid FROM runner WHERE vendor = ?1 AND brand = ?2",
[vendor, brand],
|r| r.get(0),
)?
}
},
)
}
pub(crate) fn corpus_id_or_insert(&self, path: &Path) -> anyhow::Result<Id> {
let path = path.to_str().context("corpus root cannot contain illformed UTF-8")?;
Ok(
match self
.con
.query_row("SELECT rowid FROM corpus WHERE root = ?1", [path], |r| r.get(0))
.optional()?
{
Some(existing) => existing,
None => {
self.con.execute("INSERT INTO corpus (root) VALUES (?1)", [path])?;
self.con
.query_row("SELECT rowid FROM corpus WHERE root = ?1", [path], |r| r.get(0))?
}
},
)
}
pub(crate) fn gitoxide_version_id_or_insert(&self) -> anyhow::Result<Id> {
Ok(
match self
.con
.query_row(
"SELECT rowid FROM gitoxide_version WHERE version = ?1",
[&self.gitoxide_version],
|r| r.get(0),
)
.optional()?
{
Some(existing) => existing,
None => {
self.con.execute(
"INSERT INTO gitoxide_version (version) VALUES (?1)",
[&self.gitoxide_version],
)?;
self.con.query_row(
"SELECT rowid FROM gitoxide_version WHERE version = ?1",
[&self.gitoxide_version],
|r| r.get(0),
)?
}
},
)
}
}
}
2 changes: 1 addition & 1 deletion src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub fn main() -> Result<()> {
progress_keep_open,
None,
move |progress, _out, _err| {
let engine = core::corpus::Engine::open_or_create(db, progress)?;
let engine = core::corpus::Engine::open_or_create(db, env!("GITOXIDE_VERSION").into(), progress)?;
match cmd {
crate::plumbing::options::corpus::SubCommands::Run => engine.run(path),
}
Expand Down

0 comments on commit fcbda1d

Please sign in to comment.