Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit bcba748

Browse files
committed
add repo.destroy() function, fix #57
1 parent 5317fc2 commit bcba748

File tree

12 files changed

+196
-35
lines changed

12 files changed

+196
-35
lines changed

src/fs/fs.rs

+7
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,13 @@ impl Fs {
609609
Fnode::add_child(&tgt_parent, &src, &name)
610610
})
611611
}
612+
613+
/// Destroy the whole file system
614+
#[inline]
615+
pub fn destroy(uri: &str) -> Result<()> {
616+
let mut vol = Volume::new(uri)?;
617+
vol.destroy()
618+
}
612619
}
613620

614621
impl Drop for Fs {

src/repo.rs

+10
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,7 @@ impl Repo {
727727
/// damaged. If it is the case, use
728728
/// [repair_super_block](struct.Repo.html#method.repair_super_block)
729729
/// to restore super block before re-opening the repo.
730+
#[inline]
730731
pub fn reset_password(
731732
&mut self,
732733
old_pwd: &str,
@@ -959,6 +960,15 @@ impl Repo {
959960
) -> Result<()> {
960961
self.fs.rename(from.as_ref(), to.as_ref())
961962
}
963+
964+
/// Permanently destroy a repository specified by `uri`.
965+
///
966+
/// This will permanently delete all files and directories in a repository
967+
/// regardless it is opened or not. Use it with caution.
968+
#[inline]
969+
pub fn destroy(uri: &str) -> Result<()> {
970+
Fs::destroy(uri)
971+
}
962972
}
963973

964974
impl Debug for Repo {

src/volume/storage/faulty/faulty.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl Storable for FaultyStorage {
5858
fn init(&mut self, _crypto: Crypto, _key: Key) -> Result<()> {
5959
let mut inner = self.inner.write().unwrap();
6060
assert!(!inner.contains_key(&self.loc));
61-
inner.insert(self.loc.to_string(), MemStorage::new());
61+
inner.insert(self.loc.to_string(), MemStorage::new("faulty"));
6262
Ok(())
6363
}
6464

@@ -165,6 +165,11 @@ impl Storable for FaultyStorage {
165165
let ms = inner.get_refresh(&self.loc).unwrap();
166166
ms.flush()
167167
}
168+
169+
#[inline]
170+
fn destroy(&mut self) -> Result<()> {
171+
unimplemented!()
172+
}
168173
}
169174

170175
impl Debug for FaultyStorage {

src/volume/storage/file/file.rs

+9
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,15 @@ impl Storable for FileStorage {
233233
fn flush(&mut self) -> Result<()> {
234234
self.idx_mgr.flush()
235235
}
236+
237+
#[inline]
238+
fn destroy(&mut self) -> Result<()> {
239+
if self.lock_path().exists() {
240+
warn!("Destroy an opened repo");
241+
}
242+
let _ = vio::remove_dir_all(&self.base)?;
243+
Ok(())
244+
}
236245
}
237246

238247
impl Drop for FileStorage {

src/volume/storage/mem/mem.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl MemStorage {
5757
let depot = storages.get_mut(&self.loc).unwrap();
5858
if depot.is_opened {
5959
if force {
60-
warn!("Repo was locked, forced to open");
60+
warn!("Repo is locked, forced to open");
6161
} else {
6262
return Err(Error::RepoOpened);
6363
}
@@ -194,6 +194,16 @@ impl Storable for MemStorage {
194194
fn flush(&mut self) -> Result<()> {
195195
Ok(())
196196
}
197+
198+
fn destroy(&mut self) -> Result<()> {
199+
let mut storages = STORAGES.lock().unwrap();
200+
if let Some(depot) = storages.remove(&self.loc) {
201+
if depot.is_opened {
202+
warn!("Destroyed an opened repo");
203+
}
204+
}
205+
Ok(())
206+
}
197207
}
198208

199209
impl Drop for MemStorage {

src/volume/storage/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ pub trait Storable: Debug + Send + Sync {
8383
// flush possibly buffered wal, address and block to storage,
8484
// storage must gurantee write is persistent
8585
fn flush(&mut self) -> Result<()>;
86+
87+
// permanently destroy this storage
88+
fn destroy(&mut self) -> Result<()>;
8689
}
8790

8891
/// Dummy storage
@@ -173,4 +176,9 @@ impl Storable for DummyStorage {
173176
fn flush(&mut self) -> Result<()> {
174177
unimplemented!()
175178
}
179+
180+
#[inline]
181+
fn destroy(&mut self) -> Result<()> {
182+
unimplemented!()
183+
}
176184
}

src/volume/storage/redis/redis.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt::{self, Debug};
22
use std::sync::Mutex;
33

4-
use redis::{Client, Commands, Connection};
4+
use redis::{self, Client, Commands, Connection};
55

66
use base::crypto::{Crypto, Key};
77
use base::IntoRef;
@@ -230,6 +230,22 @@ impl Storable for RedisStorage {
230230
fn flush(&mut self) -> Result<()> {
231231
Ok(())
232232
}
233+
234+
fn destroy(&mut self) -> Result<()> {
235+
let key = repo_lock_key();
236+
if self.get_bytes(&key).is_ok() {
237+
// repo is locked
238+
warn!("Destroy an opened repo");
239+
}
240+
match self.conn {
241+
Some(ref conn) => {
242+
let mut conn = conn.lock().unwrap();
243+
redis::cmd("FLUSHDB").execute(&mut *conn);
244+
Ok(())
245+
}
246+
None => unreachable!(),
247+
}
248+
}
233249
}
234250

235251
impl Drop for RedisStorage {

src/volume/storage/sqlite/sqlite.rs

+26-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::thread::panicking;
77
use libsqlite3_sys as ffi;
88

99
use base::crypto::{Crypto, Key};
10+
use base::vio;
1011
use error::{Error, Result};
1112
use trans::Eid;
1213
use volume::address::Span;
@@ -117,8 +118,8 @@ fn run_select_blob(stmt: *mut ffi::sqlite3_stmt) -> Result<Vec<u8>> {
117118

118119
/// Sqlite Storage
119120
pub struct SqliteStorage {
120-
is_attached: bool, // attached to sqlite db
121-
filename: CString,
121+
is_attached: bool, // attached to sqlite db
122+
file_path: CString, // database file path
122123
db: *mut ffi::sqlite3,
123124
stmts: Vec<*mut ffi::sqlite3_stmt>,
124125
}
@@ -131,10 +132,10 @@ impl SqliteStorage {
131132
const TBL_ADDRESSES: &'static str = "addresses";
132133
const TBL_BLOCKS: &'static str = "blocks";
133134

134-
pub fn new(filename: &str) -> Self {
135+
pub fn new(file_path: &str) -> Self {
135136
SqliteStorage {
136137
is_attached: false,
137-
filename: CString::new(filename).unwrap(),
138+
file_path: CString::new(file_path).unwrap(),
138139
db: ptr::null_mut(),
139140
stmts: Vec::with_capacity(14),
140141
}
@@ -196,7 +197,7 @@ impl SqliteStorage {
196197
))?;
197198
self.prepare_sql(format!(
198199
"
199-
INSERT INTO {}(suffix, data) VALUES (?, ?)
200+
INSERT OR REPLACE INTO {}(suffix, data) VALUES (?, ?)
200201
",
201202
Self::TBL_SUPER_BLOCK
202203
))?;
@@ -297,7 +298,7 @@ impl Storable for SqliteStorage {
297298
let mut db: *mut ffi::sqlite3 = ptr::null_mut();
298299
let result = unsafe {
299300
ffi::sqlite3_open_v2(
300-
self.filename.as_ptr(),
301+
self.file_path.as_ptr(),
301302
&mut db,
302303
ffi::SQLITE_OPEN_READONLY,
303304
ptr::null(),
@@ -312,7 +313,7 @@ impl Storable for SqliteStorage {
312313
fn connect(&mut self, _force: bool) -> Result<()> {
313314
let result = unsafe {
314315
ffi::sqlite3_open_v2(
315-
self.filename.as_ptr(),
316+
self.file_path.as_ptr(),
316317
&mut self.db,
317318
ffi::SQLITE_OPEN_READWRITE
318319
| ffi::SQLITE_OPEN_CREATE
@@ -524,6 +525,23 @@ impl Storable for SqliteStorage {
524525
fn flush(&mut self) -> Result<()> {
525526
Ok(())
526527
}
528+
529+
#[inline]
530+
fn destroy(&mut self) -> Result<()> {
531+
if self.prepare_stmts().is_ok() {
532+
let stmt = self.stmts[0];
533+
reset_stmt(stmt)?;
534+
match unsafe { ffi::sqlite3_step(stmt) } {
535+
ffi::SQLITE_ROW => {
536+
// repo is locked
537+
warn!("Destroy an opened repo");
538+
}
539+
_ => {}
540+
}
541+
}
542+
let _ = vio::remove_file(self.file_path.to_str().unwrap())?;
543+
Ok(())
544+
}
527545
}
528546

529547
impl Drop for SqliteStorage {
@@ -560,7 +578,7 @@ impl Drop for SqliteStorage {
560578
impl Debug for SqliteStorage {
561579
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
562580
f.debug_struct("SqliteStorage")
563-
.field("filename", &self.filename)
581+
.field("file_path", &self.file_path)
564582
.finish()
565583
}
566584
}

src/volume/storage/storage.rs

+5
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@ impl Storage {
303303
pub fn flush(&mut self) -> Result<()> {
304304
self.depot.flush()
305305
}
306+
307+
#[inline]
308+
pub fn destroy(&mut self) -> Result<()> {
309+
self.depot.destroy()
310+
}
306311
}
307312

308313
impl Default for Storage {

src/volume/storage/zbox/zbox.rs

+5
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,11 @@ impl Storable for ZboxStorage {
270270
let mut local_cache = self.local_cache.write().unwrap();
271271
local_cache.flush()
272272
}
273+
274+
#[inline]
275+
fn destroy(&mut self) -> Result<()> {
276+
unimplemented!()
277+
}
273278
}
274279

275280
impl Debug for ZboxStorage {

src/volume/volume.rs

+9
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ impl Volume {
174174
storage.get_allocator()
175175
}
176176

177+
// delete a wal
177178
#[inline]
178179
pub fn del_wal(&mut self, id: &Eid) -> Result<()> {
179180
let mut storage = self.storage.write().unwrap();
@@ -192,6 +193,14 @@ impl Volume {
192193
let mut storage = self.storage.write().unwrap();
193194
storage.flush()
194195
}
196+
197+
// permanently destroy a volume
198+
#[inline]
199+
pub fn destroy(&mut self) -> Result<()> {
200+
let mut storage = self.storage.write().unwrap();
201+
storage.connect(false)?;
202+
storage.destroy()
203+
}
195204
}
196205

197206
impl IntoRef for Volume {}

0 commit comments

Comments
 (0)