feat: Improve OurDBFS ID generation and data persistence
- Use a counter for consistent ID generation in OurDBFS: This eliminates reliance on timestamps, preventing ID collisions and improving data integrity. - Refactor save methods to directly use the VFS's save_entry function: This simplifies the code and reduces redundancy across different file system entity types (Directory, File, Symlink). - Update `save_entry` in OurDBFS to use IDs for database updates: This ensures data is correctly updated in the database based on the unique ID of each entry. This also fixes potential issues with overwriting data.
This commit is contained in:
@@ -15,7 +15,7 @@ pub mut:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut self Directory) save() ! {
|
pub fn (mut self Directory) save() ! {
|
||||||
self.metadata.id = self.myvfs.save_entry(self)!
|
self.myvfs.save_entry(self)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// write creates a new file or writes to an existing file
|
// write creates a new file or writes to an existing file
|
||||||
@@ -45,7 +45,7 @@ pub fn (mut dir Directory) write(name string, content string) !&File {
|
|||||||
current_time := time.now().unix()
|
current_time := time.now().unix()
|
||||||
file = &File{
|
file = &File{
|
||||||
metadata: Metadata{
|
metadata: Metadata{
|
||||||
// id: u32(time.now().unix())
|
id: dir.myvfs.get_next_id()
|
||||||
name: name
|
name: name
|
||||||
file_type: .file
|
file_type: .file
|
||||||
size: u64(content.len)
|
size: u64(content.len)
|
||||||
@@ -62,11 +62,11 @@ pub fn (mut dir Directory) write(name string, content string) !&File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save new file to DB
|
// Save new file to DB
|
||||||
file.metadata.id = dir.myvfs.save_entry(file)!
|
dir.myvfs.save_entry(file)!
|
||||||
|
|
||||||
// Update children list
|
// Update children list
|
||||||
dir.children << file.metadata.id
|
dir.children << file.metadata.id
|
||||||
dir.metadata.id = dir.myvfs.save_entry(dir)!
|
dir.myvfs.save_entry(dir)!
|
||||||
} else {
|
} else {
|
||||||
// Update existing file
|
// Update existing file
|
||||||
file.write(content)!
|
file.write(content)!
|
||||||
@@ -141,7 +141,7 @@ pub fn (mut dir Directory) mkdir(name string) !&Directory {
|
|||||||
current_time := time.now().unix()
|
current_time := time.now().unix()
|
||||||
mut new_dir := Directory{
|
mut new_dir := Directory{
|
||||||
metadata: Metadata{
|
metadata: Metadata{
|
||||||
// id: u32(time.now().unix()) // Use timestamp as ID
|
id: dir.myvfs.get_next_id()
|
||||||
name: name
|
name: name
|
||||||
file_type: .directory
|
file_type: .directory
|
||||||
created_at: current_time
|
created_at: current_time
|
||||||
@@ -157,11 +157,11 @@ pub fn (mut dir Directory) mkdir(name string) !&Directory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save new directory to DB
|
// Save new directory to DB
|
||||||
new_dir.metadata.id = dir.myvfs.save_entry(new_dir)!
|
dir.myvfs.save_entry(new_dir)!
|
||||||
|
|
||||||
// Update children list
|
// Update children list
|
||||||
dir.children << new_dir.metadata.id
|
dir.children << new_dir.metadata.id
|
||||||
dir.metadata.id = dir.myvfs.save_entry(dir)!
|
dir.myvfs.save_entry(dir)!
|
||||||
|
|
||||||
return &new_dir
|
return &new_dir
|
||||||
}
|
}
|
||||||
@@ -180,6 +180,7 @@ pub fn (mut dir Directory) touch(name string) !&File {
|
|||||||
current_time := time.now().unix()
|
current_time := time.now().unix()
|
||||||
mut new_file := File{
|
mut new_file := File{
|
||||||
metadata: Metadata{
|
metadata: Metadata{
|
||||||
|
id: dir.myvfs.get_next_id()
|
||||||
name: name
|
name: name
|
||||||
file_type: .file
|
file_type: .file
|
||||||
size: 0
|
size: 0
|
||||||
@@ -196,11 +197,11 @@ pub fn (mut dir Directory) touch(name string) !&File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save new file to DB
|
// Save new file to DB
|
||||||
new_file.metadata.id = dir.myvfs.save_entry(new_file)!
|
dir.myvfs.save_entry(new_file)!
|
||||||
|
|
||||||
// Update children list
|
// Update children list
|
||||||
dir.children << new_file.metadata.id
|
dir.children << new_file.metadata.id
|
||||||
dir.metadata.id = dir.myvfs.save_entry(dir)!
|
dir.myvfs.save_entry(dir)!
|
||||||
|
|
||||||
return &new_file
|
return &new_file
|
||||||
}
|
}
|
||||||
@@ -236,7 +237,7 @@ pub fn (mut dir Directory) rm(name string) ! {
|
|||||||
|
|
||||||
// Update children list
|
// Update children list
|
||||||
dir.children.delete(found_idx)
|
dir.children.delete(found_idx)
|
||||||
dir.metadata.id = dir.myvfs.save_entry(dir)!
|
dir.myvfs.save_entry(dir)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_children returns all immediate children as FSEntry objects
|
// get_children returns all immediate children as FSEntry objects
|
||||||
@@ -266,9 +267,7 @@ pub fn (mut dir Directory) delete() ! {
|
|||||||
dir.children.clear()
|
dir.children.clear()
|
||||||
|
|
||||||
// Save the updated directory
|
// Save the updated directory
|
||||||
dir.metadata.id = dir.myvfs.save_entry(dir) or {
|
dir.myvfs.save_entry(dir) or { return error('Failed to save directory: ${err}') }
|
||||||
return error('Failed to save directory: ${err}')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add_symlink adds an existing symlink to this directory
|
// add_symlink adds an existing symlink to this directory
|
||||||
@@ -283,9 +282,9 @@ pub fn (mut dir Directory) add_symlink(mut symlink Symlink) ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save symlink to DB
|
// Save symlink to DB
|
||||||
symlink.metadata.id = dir.myvfs.save_entry(symlink)!
|
dir.myvfs.save_entry(symlink)!
|
||||||
|
|
||||||
// Add to children
|
// Add to children
|
||||||
dir.children << symlink.metadata.id
|
dir.children << symlink.metadata.id
|
||||||
dir.metadata.id = dir.myvfs.save_entry(dir)!
|
dir.myvfs.save_entry(dir)!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pub mut:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f File) save() ! {
|
pub fn (mut f File) save() ! {
|
||||||
f.metadata.id = f.myvfs.save_entry(f)!
|
f.myvfs.save_entry(f)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// write updates the file's content
|
// write updates the file's content
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pub mut:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut sl Symlink) save() ! {
|
pub fn (mut sl Symlink) save() ! {
|
||||||
sl.metadata.id = sl.myvfs.save_entry(sl)!
|
sl.myvfs.save_entry(sl)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// update_target changes the symlink's target path
|
// update_target changes the symlink's target path
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
module ourdb_fs
|
module ourdb_fs
|
||||||
|
|
||||||
import freeflowuniverse.herolib.data.ourdb
|
import freeflowuniverse.herolib.data.ourdb
|
||||||
|
import time
|
||||||
|
|
||||||
// OurDBFS represents the virtual filesystem
|
// OurDBFS represents the virtual filesystem
|
||||||
@[heap]
|
@[heap]
|
||||||
@@ -12,6 +13,13 @@ pub mut:
|
|||||||
metadata_dir string // Directory where we store the metadata
|
metadata_dir string // Directory where we store the metadata
|
||||||
db_data &ourdb.OurDB // Database instance for persistent storage
|
db_data &ourdb.OurDB // Database instance for persistent storage
|
||||||
db_meta &ourdb.OurDB // Database instance for metadata storage
|
db_meta &ourdb.OurDB // Database instance for metadata storage
|
||||||
|
last_inserted_id u32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next ID, it should be some kind of auto-incrementing ID
|
||||||
|
pub fn (mut fs OurDBFS) get_next_id() u32 {
|
||||||
|
fs.last_inserted_id = fs.last_inserted_id + 1
|
||||||
|
return fs.last_inserted_id
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_root returns the root directory
|
// get_root returns the root directory
|
||||||
@@ -28,13 +36,22 @@ pub fn (mut fs OurDBFS) get_root() !&Directory {
|
|||||||
// Create and save new root directory
|
// Create and save new root directory
|
||||||
mut myroot := Directory{
|
mut myroot := Directory{
|
||||||
metadata: Metadata{
|
metadata: Metadata{
|
||||||
|
id: fs.get_next_id()
|
||||||
file_type: .directory
|
file_type: .directory
|
||||||
|
name: ''
|
||||||
|
created_at: time.now().unix()
|
||||||
|
modified_at: time.now().unix()
|
||||||
|
accessed_at: time.now().unix()
|
||||||
|
mode: 0o755 // default directory permissions
|
||||||
|
owner: 'user' // TODO: get from system
|
||||||
|
group: 'user' // TODO: get from system
|
||||||
}
|
}
|
||||||
parent_id: 0
|
parent_id: 0
|
||||||
myvfs: &fs
|
myvfs: &fs
|
||||||
}
|
}
|
||||||
myroot.save()!
|
myroot.save()!
|
||||||
fs.root_id = myroot.metadata.id
|
fs.root_id = myroot.metadata.id
|
||||||
|
myroot.save()!
|
||||||
|
|
||||||
return &myroot
|
return &myroot
|
||||||
}
|
}
|
||||||
@@ -76,19 +93,19 @@ pub fn (mut fs OurDBFS) save_entry(entry FSEntry) !u32 {
|
|||||||
match entry {
|
match entry {
|
||||||
Directory {
|
Directory {
|
||||||
encoded := entry.encode()
|
encoded := entry.encode()
|
||||||
return fs.db_meta.set(data: encoded) or {
|
return fs.db_meta.set(id: entry.metadata.id, data: encoded) or {
|
||||||
return error('Failed to save directory on id:${entry.metadata.id}: ${err}')
|
return error('Failed to save directory on id:${entry.metadata.id}: ${err}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File {
|
File {
|
||||||
encoded := entry.encode()
|
encoded := entry.encode()
|
||||||
return fs.db_meta.set(data: encoded) or {
|
return fs.db_meta.set(id: entry.metadata.id, data: encoded) or {
|
||||||
return error('Failed to save file on id:${entry.metadata.id}: ${err}')
|
return error('Failed to save file on id:${entry.metadata.id}: ${err}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Symlink {
|
Symlink {
|
||||||
encoded := entry.encode()
|
encoded := entry.encode()
|
||||||
return fs.db_meta.set(data: encoded) or {
|
return fs.db_meta.set(id: entry.metadata.id, data: encoded) or {
|
||||||
return error('Failed to save symlink on id:${entry.metadata.id}: ${err}')
|
return error('Failed to save symlink on id:${entry.metadata.id}: ${err}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ pub enum FileType {
|
|||||||
// Metadata represents the common metadata for both files and directories
|
// Metadata represents the common metadata for both files and directories
|
||||||
pub struct Metadata {
|
pub struct Metadata {
|
||||||
pub mut:
|
pub mut:
|
||||||
|
id u32 // name of file or directory
|
||||||
name string // name of file or directory
|
name string // name of file or directory
|
||||||
file_type FileType
|
file_type FileType
|
||||||
size u64
|
size u64
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn new(data_dir string, metadata_dir string) !&OurDBVFS {
|
|||||||
mut core := ourdb_fs.new(
|
mut core := ourdb_fs.new(
|
||||||
data_dir: data_dir
|
data_dir: data_dir
|
||||||
metadata_dir: metadata_dir
|
metadata_dir: metadata_dir
|
||||||
incremental_mode: true
|
incremental_mode: false
|
||||||
)!
|
)!
|
||||||
|
|
||||||
return &OurDBVFS{
|
return &OurDBVFS{
|
||||||
@@ -59,13 +59,15 @@ pub fn (mut self OurDBVFS) file_write(path string, data []u8) ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut self OurDBVFS) delete(path string) ! {
|
pub fn (mut self OurDBVFS) delete(path string) ! {
|
||||||
// mut impl, rel_path := self.find_vfs(path)!
|
println('Not implemented')
|
||||||
// return impl.file_read(rel_path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut self OurDBVFS) link_delete(path string) ! {
|
pub fn (mut self OurDBVFS) link_delete(path string) ! {
|
||||||
// mut impl, rel_path := self.find_vfs(path)!
|
parent_path := os.dir(path)
|
||||||
// return impl.file_read(rel_path)
|
file_name := os.base(path)
|
||||||
|
|
||||||
|
mut parent_dir := self.get_directory(parent_path)!
|
||||||
|
parent_dir.rm(file_name)!
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut self OurDBVFS) file_delete(path string) ! {
|
pub fn (mut self OurDBVFS) file_delete(path string) ! {
|
||||||
@@ -136,7 +138,7 @@ pub fn (mut self OurDBVFS) link_create(target_path string, link_path string) !vf
|
|||||||
|
|
||||||
mut symlink := ourdb_fs.Symlink{
|
mut symlink := ourdb_fs.Symlink{
|
||||||
metadata: ourdb_fs.Metadata{
|
metadata: ourdb_fs.Metadata{
|
||||||
id: u32(time.now().unix())
|
id: self.core.get_next_id()
|
||||||
name: link_name
|
name: link_name
|
||||||
file_type: .symlink
|
file_type: .symlink
|
||||||
created_at: time.now().unix()
|
created_at: time.now().unix()
|
||||||
@@ -240,6 +242,7 @@ fn convert_to_vfscore_entry(entry ourdb_fs.FSEntry) vfscore.FSEntry {
|
|||||||
|
|
||||||
fn convert_metadata(meta ourdb_fs.Metadata) vfscore.Metadata {
|
fn convert_metadata(meta ourdb_fs.Metadata) vfscore.Metadata {
|
||||||
return vfscore.Metadata{
|
return vfscore.Metadata{
|
||||||
|
id: meta.id
|
||||||
name: meta.name
|
name: meta.name
|
||||||
file_type: match meta.file_type {
|
file_type: match meta.file_type {
|
||||||
.file { vfscore.FileType.file }
|
.file { vfscore.FileType.file }
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ fn test_vfsourdb() ! {
|
|||||||
assert read_content == test_content
|
assert read_content == test_content
|
||||||
|
|
||||||
// Test directory listing
|
// Test directory listing
|
||||||
entries := vfs.dir_list('/test_dir')!
|
mut entries := vfs.dir_list('/test_dir')!
|
||||||
assert entries.len == 1
|
assert entries.len == 1
|
||||||
assert entries[0].get_metadata().name == 'test.txt'
|
assert entries[0].get_metadata().name == 'test.txt'
|
||||||
|
|
||||||
@@ -57,10 +57,17 @@ fn test_vfsourdb() ! {
|
|||||||
link_target := vfs.link_read('/test_dir/test_link')!
|
link_target := vfs.link_read('/test_dir/test_link')!
|
||||||
assert link_target == '/test_dir/test.txt'
|
assert link_target == '/test_dir/test.txt'
|
||||||
|
|
||||||
|
// Test symlink deletion
|
||||||
|
vfs.link_delete('/test_dir/test_link')!
|
||||||
|
assert vfs.exists('/test_dir/test_link') == false
|
||||||
|
|
||||||
// Test file deletion
|
// Test file deletion
|
||||||
vfs.file_delete('/test_dir/test.txt')!
|
vfs.file_delete('/test_dir/test.txt')!
|
||||||
assert vfs.exists('/test_dir/test.txt') == false
|
assert vfs.exists('/test_dir/test.txt') == false
|
||||||
|
|
||||||
|
entries = vfs.dir_list('/test_dir')!
|
||||||
|
assert entries.len == 0
|
||||||
|
|
||||||
// Test directory deletion
|
// Test directory deletion
|
||||||
vfs.dir_delete('/test_dir')!
|
vfs.dir_delete('/test_dir')!
|
||||||
assert vfs.exists('/test_dir') == false
|
assert vfs.exists('/test_dir') == false
|
||||||
|
|||||||
Reference in New Issue
Block a user