mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Add support for _not_ creating a DB if one does not exist
This commit is contained in:
parent
9e5c0001c4
commit
67fc422311
5 changed files with 46 additions and 25 deletions
|
@ -14,7 +14,7 @@ static void test_replica_creation(void) {
|
|||
|
||||
// creating an on-disk replica does not crash
|
||||
static void test_replica_creation_disk(void) {
|
||||
TCReplica *rep = tc_replica_new_on_disk(tc_string_borrow("test-db"), NULL);
|
||||
TCReplica *rep = tc_replica_new_on_disk(tc_string_borrow("test-db"), true, NULL);
|
||||
TEST_ASSERT_NOT_NULL(rep);
|
||||
TEST_ASSERT_NULL(tc_replica_error(rep).ptr);
|
||||
tc_replica_free(rep);
|
||||
|
|
|
@ -140,6 +140,7 @@ pub unsafe extern "C" fn tc_replica_new_in_memory() -> *mut TCReplica {
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tc_replica_new_on_disk(
|
||||
path: TCString,
|
||||
create_if_missing: bool,
|
||||
error_out: *mut TCString,
|
||||
) -> *mut TCReplica {
|
||||
wrap_constructor(
|
||||
|
@ -150,6 +151,7 @@ pub unsafe extern "C" fn tc_replica_new_on_disk(
|
|||
let mut path = unsafe { TCString::val_from_arg(path) };
|
||||
let storage = StorageConfig::OnDisk {
|
||||
taskdb_dir: path.to_path_buf_mut()?,
|
||||
create_if_missing,
|
||||
}
|
||||
.into_storage()?;
|
||||
|
||||
|
|
|
@ -492,7 +492,9 @@ struct TCReplica *tc_replica_new_in_memory(void);
|
|||
* is written to the error_out parameter (if it is not NULL) and NULL is returned. The caller
|
||||
* must free this string.
|
||||
*/
|
||||
struct TCReplica *tc_replica_new_on_disk(struct TCString path, struct TCString *error_out);
|
||||
struct TCReplica *tc_replica_new_on_disk(struct TCString path,
|
||||
bool create_if_missing,
|
||||
struct TCString *error_out);
|
||||
|
||||
/**
|
||||
* Get a list of all tasks in the replica.
|
||||
|
|
|
@ -7,6 +7,9 @@ pub enum StorageConfig {
|
|||
OnDisk {
|
||||
/// Path containing the task DB.
|
||||
taskdb_dir: PathBuf,
|
||||
|
||||
/// Create the DB if it does not already exist
|
||||
create_if_missing: bool,
|
||||
},
|
||||
/// Store the data in memory. This is only useful for testing.
|
||||
InMemory,
|
||||
|
@ -15,7 +18,10 @@ pub enum StorageConfig {
|
|||
impl StorageConfig {
|
||||
pub fn into_storage(self) -> anyhow::Result<Box<dyn Storage>> {
|
||||
Ok(match self {
|
||||
StorageConfig::OnDisk { taskdb_dir } => Box::new(SqliteStorage::new(taskdb_dir)?),
|
||||
StorageConfig::OnDisk {
|
||||
taskdb_dir,
|
||||
create_if_missing,
|
||||
} => Box::new(SqliteStorage::new(taskdb_dir, create_if_missing)?),
|
||||
StorageConfig::InMemory => Box::new(InMemoryStorage::new()),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::storage::{ReplicaOp, Storage, StorageTxn, TaskMap, VersionId, DEFAULT_BASE_VERSION};
|
||||
use anyhow::Context;
|
||||
use rusqlite::types::{FromSql, ToSql};
|
||||
use rusqlite::{params, Connection, OptionalExtension};
|
||||
use rusqlite::{params, Connection, OpenFlags, OptionalExtension};
|
||||
use std::path::Path;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -76,13 +76,24 @@ pub struct SqliteStorage {
|
|||
}
|
||||
|
||||
impl SqliteStorage {
|
||||
pub fn new<P: AsRef<Path>>(directory: P) -> anyhow::Result<SqliteStorage> {
|
||||
pub fn new<P: AsRef<Path>>(
|
||||
directory: P,
|
||||
create_if_missing: bool,
|
||||
) -> anyhow::Result<SqliteStorage> {
|
||||
if create_if_missing {
|
||||
// Ensure parent folder exists
|
||||
std::fs::create_dir_all(&directory)?;
|
||||
}
|
||||
|
||||
// Open (or create) database
|
||||
let db_file = directory.as_ref().join("taskchampion.sqlite3");
|
||||
let con = Connection::open(db_file)?;
|
||||
let mut flags = OpenFlags::SQLITE_OPEN_READ_WRITE
|
||||
| OpenFlags::SQLITE_OPEN_NO_MUTEX
|
||||
| OpenFlags::SQLITE_OPEN_URI;
|
||||
if create_if_missing {
|
||||
flags |= OpenFlags::SQLITE_OPEN_CREATE;
|
||||
}
|
||||
let con = Connection::open_with_flags(db_file, flags)?;
|
||||
|
||||
// Initialize database
|
||||
let queries = vec![
|
||||
|
@ -369,7 +380,7 @@ mod test {
|
|||
fn test_empty_dir() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let non_existant = tmp_dir.path().join("subdir");
|
||||
let mut storage = SqliteStorage::new(&non_existant)?;
|
||||
let mut storage = SqliteStorage::new(&non_existant, true)?;
|
||||
let uuid = Uuid::new_v4();
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -387,7 +398,7 @@ mod test {
|
|||
#[test]
|
||||
fn drop_transaction() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid1 = Uuid::new_v4();
|
||||
let uuid2 = Uuid::new_v4();
|
||||
|
||||
|
@ -416,7 +427,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_create() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid = Uuid::new_v4();
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -434,7 +445,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_create_exists() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid = Uuid::new_v4();
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -452,7 +463,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_get_missing() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid = Uuid::new_v4();
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -465,7 +476,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_set_task() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid = Uuid::new_v4();
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -486,7 +497,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_delete_task_missing() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid = Uuid::new_v4();
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -498,7 +509,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_delete_task_exists() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid = Uuid::new_v4();
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -515,7 +526,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_all_tasks_empty() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
let tasks = txn.all_tasks()?;
|
||||
|
@ -527,7 +538,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_all_tasks_and_uuids() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid1 = Uuid::new_v4();
|
||||
let uuid2 = Uuid::new_v4();
|
||||
{
|
||||
|
@ -581,7 +592,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_base_version_default() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
assert_eq!(txn.base_version()?, DEFAULT_BASE_VERSION);
|
||||
|
@ -592,7 +603,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_base_version_setting() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let u = Uuid::new_v4();
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -609,7 +620,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_operations() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid1 = Uuid::new_v4();
|
||||
let uuid2 = Uuid::new_v4();
|
||||
let uuid3 = Uuid::new_v4();
|
||||
|
@ -694,7 +705,7 @@ mod test {
|
|||
#[test]
|
||||
fn get_working_set_empty() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
|
||||
{
|
||||
let mut txn = storage.txn()?;
|
||||
|
@ -708,7 +719,7 @@ mod test {
|
|||
#[test]
|
||||
fn add_to_working_set() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid1 = Uuid::new_v4();
|
||||
let uuid2 = Uuid::new_v4();
|
||||
|
||||
|
@ -731,7 +742,7 @@ mod test {
|
|||
#[test]
|
||||
fn clear_working_set() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid1 = Uuid::new_v4();
|
||||
let uuid2 = Uuid::new_v4();
|
||||
|
||||
|
@ -762,7 +773,7 @@ mod test {
|
|||
#[test]
|
||||
fn set_working_set_item() -> anyhow::Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path())?;
|
||||
let mut storage = SqliteStorage::new(&tmp_dir.path(), true)?;
|
||||
let uuid1 = Uuid::new_v4();
|
||||
let uuid2 = Uuid::new_v4();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue