aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTeddy Wing2021-06-11 02:39:39 +0200
committerTeddy Wing2021-06-11 02:39:39 +0200
commit08c06d217cd2c63de4f032844d6d7856a0fb9657 (patch)
tree05c87375e5ad95f5f7cf687fa763695c0c2021c9 /src
parent5a115da66b98ce4604e98c47cbba0dcb617b5c10 (diff)
downloadreflectub-08c06d217cd2c63de4f032844d6d7856a0fb9657.tar.bz2
Replace 'sqlx' with 'rusqlite'
Trying to get rid of async. This compiles, but fails with the following runtime error: Error code 21: Library used incorrectly Need to investigate further.
Diffstat (limited to 'src')
-rw-r--r--src/database.rs173
-rw-r--r--src/main.rs16
2 files changed, 103 insertions, 86 deletions
diff --git a/src/database.rs b/src/database.rs
index 2c1c0c8..f23fcd4 100644
--- a/src/database.rs
+++ b/src/database.rs
@@ -16,7 +16,7 @@
// along with Reflectub. If not, see <https://www.gnu.org/licenses/>.
-use sqlx::{self, ConnectOptions, Connection, Executor, Row};
+use rusqlite::{self, OptionalExtension};
use thiserror;
use crate::github;
@@ -54,59 +54,66 @@ impl From<&github::Repo> for Repo {
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("database error")]
- Db(#[from] sqlx::Error),
+ Db(#[from] rusqlite::Error),
}
#[derive(Debug)]
pub struct Db {
- connection: sqlx::SqliteConnection,
+ connection: rusqlite::Connection,
}
impl Db {
/// Open a connection to the database.
- pub async fn connect(path: &str) -> Result<Self, Error> {
+ pub fn connect(path: &str) -> Result<Self, Error> {
Ok(
Db {
- connection: sqlx::sqlite::SqliteConnectOptions::new()
- .filename(path)
- .create_if_missing(true)
- .connect()
- .await?,
+ connection: rusqlite::Connection::open_with_flags(
+ path,
+ rusqlite::OpenFlags::SQLITE_OPEN_CREATE,
+ )?,
}
)
}
/// Initialise the database with tables and indexes.
- pub async fn create(&mut self) -> Result<(), Error> {
- let mut tx = self.connection.begin().await?;
-
- tx.execute(r#"
- CREATE TABLE IF NOT EXISTS repositories (
- id INTEGER PRIMARY KEY,
- name TEXT NOT NULL,
- description TEXT,
- updated_at TEXT NOT NULL
- );
- "#).await?;
-
- tx.execute(r#"
- CREATE UNIQUE INDEX IF NOT EXISTS idx_repositories_id
- ON repositories (id);
- "#).await?;
-
- tx.commit().await?;
+ pub fn create(&mut self) -> Result<(), Error> {
+ let tx = self.connection.transaction()?;
+
+ tx.execute(
+ r#"
+ CREATE TABLE IF NOT EXISTS repositories (
+ id INTEGER PRIMARY KEY,
+ name TEXT NOT NULL,
+ description TEXT,
+ updated_at TEXT NOT NULL
+ );
+ "#,
+ [],
+ )?;
+
+ tx.execute(
+ r#"
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_repositories_id
+ ON repositories (id);
+ "#,
+ [],
+ )?;
+
+ tx.commit()?;
Ok(())
}
/// Get a repository by its ID.
///
- /// Returns a `sqlx::Error::RowNotFound` error if the row doesn't exist.
- pub async fn repo_get(&mut self, id: i64) -> Result<Repo, Error> {
- let mut tx = self.connection.begin().await?;
+ /// Returns a `rusqlite::Error::QueryReturnedNoRows` error if the row
+ /// doesn't exist.
+ pub fn repo_get(&mut self, id: i64) -> Result<Repo, Error> {
+ let tx = self.connection.transaction()?;
- let row = sqlx::query(r#"
+ let repo = tx.query_row(
+ r#"
SELECT
id,
name,
@@ -114,41 +121,45 @@ impl Db {
updated_at
FROM repositories
WHERE id = ?
- "#)
- .bind(id)
- .fetch_one(&mut tx)
- .await?;
-
- tx.commit().await?;
-
- Ok(
- Repo {
- id: row.get(0),
- name: Some(row.get(1)),
- description: row.get(2),
- updated_at: Some(row.get(3)),
- }
- )
+ "#,
+ [id],
+ |row| {
+ Ok(
+ Repo {
+ id: row.get(0)?,
+ name: Some(row.get(1)?),
+ description: row.get(2)?,
+ updated_at: Some(row.get(3)?),
+ }
+ )
+ },
+ )?;
+
+ tx.commit()?;
+
+ Ok(repo)
}
/// Insert a new repository.
- pub async fn repo_insert(&mut self, repo: Repo) -> Result<(), Error> {
- let mut tx = self.connection.begin().await?;
+ pub fn repo_insert(&mut self, repo: Repo) -> Result<(), Error> {
+ let tx = self.connection.transaction()?;
- sqlx::query(r#"
+ tx.execute(
+ r#"
INSERT INTO repositories
(id, name, description, updated_at)
VALUES
(?, ?, ?, ?)
- "#)
- .bind(repo.id)
- .bind(&repo.name)
- .bind(&repo.description)
- .bind(&repo.updated_at)
- .execute(&mut tx)
- .await?;
+ "#,
+ rusqlite::params![
+ repo.id,
+ &repo.name,
+ &repo.description,
+ &repo.updated_at,
+ ],
+ )?;
- tx.commit().await?;
+ tx.commit()?;
Ok(())
}
@@ -157,53 +168,59 @@ impl Db {
///
/// Compares the `updated_at` field to find out whether the repository was
/// updated.
- pub async fn repo_is_updated(
+ pub fn repo_is_updated(
&mut self,
repo: &Repo,
) -> Result<bool, Error> {
- let mut tx = self.connection.begin().await?;
+ let tx = self.connection.transaction()?;
- let is_updated = match sqlx::query(r#"
+ let is_updated = match tx.query_row(
+ r#"
SELECT 1
FROM repositories
WHERE id = ?
AND datetime(updated_at) < datetime(?)
- "#)
- .bind(repo.id)
- .bind(&repo.updated_at)
- .fetch_optional(&mut tx)
- .await
+ "#,
+ rusqlite::params![
+ repo.id,
+ &repo.updated_at,
+ ],
+ |row| row.get::<usize, u8>(0),
+ )
+ .optional()
{
Ok(Some(_)) => Ok(true),
Ok(None) => Ok(false),
Err(e) => Err(e.into()),
};
- tx.commit().await?;
+ tx.commit()?;
is_updated
}
/// Update an existing repository.
- pub async fn repo_update(&mut self, repo: &Repo) -> Result<(), Error> {
- let mut tx = self.connection.begin().await?;
+ pub fn repo_update(&mut self, repo: &Repo) -> Result<(), Error> {
+ let tx = self.connection.transaction()?;
- sqlx::query(r#"
+ tx.execute(
+ r#"
UPDATE repositories
SET
name = ?,
description = ?,
updated_at = ?
WHERE id = ?
- "#)
- .bind(&repo.name)
- .bind(&repo.description)
- .bind(&repo.updated_at)
- .bind(repo.id)
- .execute(&mut tx)
- .await?;
-
- tx.commit().await?;
+ "#,
+ rusqlite::params![
+ &repo.name,
+ &repo.description,
+ &repo.updated_at,
+ repo.id,
+ ],
+ )?;
+
+ tx.commit()?;
Ok(())
}
diff --git a/src/main.rs b/src/main.rs
index 6eb4492..3e17c06 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -23,7 +23,7 @@ use filetime;
// use futures::{self, executor, future};
use getopts::Options;
use parse_size::parse_size;
-use sqlx;
+use rusqlite;
use tokio;
use tokio_stream::StreamExt;
@@ -127,12 +127,12 @@ async fn run() -> anyhow::Result<()> {
let db = Arc::new(
tokio::sync::Mutex::new(
- database::Db::connect(&database_file).await?,
+ database::Db::connect(&database_file)?,
)
);
db.lock().await
- .create().await?;
+ .create()?;
// let mut joins = futures::stream::FuturesUnordered::new();
let mut joins = Vec::with_capacity(repos.len());
@@ -206,27 +206,27 @@ async fn process_repo(
let path = clone_path(&mirror_root, &repo);
let db_repo = database::Repo::from(repo);
- match db.repo_get(id).await {
+ match db.repo_get(id) {
// If we've already seen the repo and it's been updated, fetch the
// latest.
Ok(current_repo) => {
- if db.repo_is_updated(&db_repo).await? {
+ if db.repo_is_updated(&db_repo)? {
update(&path, &current_repo, &repo)?;
- db.repo_update(&db_repo).await?;
+ db.repo_update(&db_repo)?;
}
},
// If the repo doesn't exist, mirror it and store it in the
// database.
- Err(database::Error::Db(sqlx::Error::RowNotFound)) => {
+ Err(database::Error::Db(rusqlite::Error::QueryReturnedNoRows)) => {
mirror(
&path,
&repo,
base_cgitrc.as_ref(),
)?;
- db.repo_insert(db_repo).await?;
+ db.repo_insert(db_repo)?;
},
Err(e) => anyhow::bail!(e),