Skip to content

Commit 318a395

Browse files
remove left over Database code from workspace crate (#197)
1 parent fd0a1c1 commit 318a395

File tree

4 files changed

+47
-165
lines changed

4 files changed

+47
-165
lines changed

crates/djls-server/src/db.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use std::path::Path;
88
use std::path::PathBuf;
99
use std::sync::Arc;
10+
#[cfg(test)]
11+
use std::sync::Mutex;
1012

1113
use dashmap::DashMap;
1214
use djls_templates::db::Db as TemplateDb;
@@ -31,15 +33,49 @@ pub struct DjangoDatabase {
3133
files: Arc<DashMap<PathBuf, SourceFile>>,
3234

3335
storage: salsa::Storage<Self>,
36+
37+
// The logs are only used for testing and demonstrating reuse:
38+
#[cfg(test)]
39+
#[allow(dead_code)]
40+
logs: Arc<Mutex<Option<Vec<String>>>>,
41+
}
42+
43+
#[cfg(test)]
44+
impl Default for DjangoDatabase {
45+
fn default() -> Self {
46+
use djls_workspace::InMemoryFileSystem;
47+
48+
let logs = <Arc<Mutex<Option<Vec<String>>>>>::default();
49+
Self {
50+
fs: Arc::new(InMemoryFileSystem::new()),
51+
files: Arc::new(DashMap::new()),
52+
storage: salsa::Storage::new(Some(Box::new({
53+
let logs = logs.clone();
54+
move |event| {
55+
eprintln!("Event: {event:?}");
56+
// Log interesting events, if logging is enabled
57+
if let Some(logs) = &mut *logs.lock().unwrap() {
58+
// only log interesting events
59+
if let salsa::EventKind::WillExecute { .. } = event.kind {
60+
logs.push(format!("Event: {event:?}"));
61+
}
62+
}
63+
}
64+
}))),
65+
logs,
66+
}
67+
}
3468
}
3569

3670
impl DjangoDatabase {
3771
/// Create a new [`DjangoDatabase`] with the given file system and file map.
3872
pub fn new(file_system: Arc<dyn FileSystem>, files: Arc<DashMap<PathBuf, SourceFile>>) -> Self {
3973
Self {
40-
storage: salsa::Storage::new(None),
4174
fs: file_system,
4275
files,
76+
storage: salsa::Storage::new(None),
77+
#[cfg(test)]
78+
logs: Arc::new(Mutex::new(None)),
4379
}
4480
}
4581

crates/djls-workspace/src/db.rs

Lines changed: 0 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,7 @@
2121
//! ```
2222
2323
use std::path::Path;
24-
use std::path::PathBuf;
2524
use std::sync::Arc;
26-
#[cfg(test)]
27-
use std::sync::Mutex;
28-
29-
use dashmap::DashMap;
30-
use salsa::Setter;
3125

3226
use crate::FileKind;
3327
use crate::FileSystem;
@@ -45,156 +39,6 @@ pub trait Db: salsa::Database {
4539
fn read_file_content(&self, path: &Path) -> std::io::Result<String>;
4640
}
4741

48-
/// Temporary concrete database for workspace.
49-
///
50-
/// This will be moved to the server crate in the refactoring.
51-
/// For now, it's kept here to avoid breaking existing code.
52-
#[salsa::db]
53-
#[derive(Clone)]
54-
pub struct Database {
55-
storage: salsa::Storage<Self>,
56-
57-
/// File system for reading file content (checks buffers first, then disk).
58-
fs: Arc<dyn FileSystem>,
59-
60-
/// Maps paths to [`SourceFile`] entities for O(1) lookup.
61-
files: Arc<DashMap<PathBuf, SourceFile>>,
62-
63-
// The logs are only used for testing and demonstrating reuse:
64-
#[cfg(test)]
65-
#[allow(dead_code)]
66-
logs: Arc<Mutex<Option<Vec<String>>>>,
67-
}
68-
69-
#[cfg(test)]
70-
impl Default for Database {
71-
fn default() -> Self {
72-
use crate::fs::InMemoryFileSystem;
73-
74-
let logs = <Arc<Mutex<Option<Vec<String>>>>>::default();
75-
Self {
76-
storage: salsa::Storage::new(Some(Box::new({
77-
let logs = logs.clone();
78-
move |event| {
79-
eprintln!("Event: {event:?}");
80-
// Log interesting events, if logging is enabled
81-
if let Some(logs) = &mut *logs.lock().unwrap() {
82-
// only log interesting events
83-
if let salsa::EventKind::WillExecute { .. } = event.kind {
84-
logs.push(format!("Event: {event:?}"));
85-
}
86-
}
87-
}
88-
}))),
89-
fs: Arc::new(InMemoryFileSystem::new()),
90-
files: Arc::new(DashMap::new()),
91-
logs,
92-
}
93-
}
94-
}
95-
96-
impl Database {
97-
pub fn new(file_system: Arc<dyn FileSystem>, files: Arc<DashMap<PathBuf, SourceFile>>) -> Self {
98-
Self {
99-
storage: salsa::Storage::new(None),
100-
fs: file_system,
101-
files,
102-
#[cfg(test)]
103-
logs: Arc::new(Mutex::new(None)),
104-
}
105-
}
106-
107-
/// Read file content through the file system.
108-
pub fn read_file_content(&self, path: &Path) -> std::io::Result<String> {
109-
self.fs.read_to_string(path)
110-
}
111-
112-
/// Get an existing [`SourceFile`] for the given path without creating it.
113-
///
114-
/// Returns `Some(SourceFile)` if the file is already tracked, `None` otherwise.
115-
/// This method uses an immutable reference and doesn't modify the database.
116-
pub fn get_file(&self, path: &Path) -> Option<SourceFile> {
117-
self.files.get(path).map(|file_ref| *file_ref)
118-
}
119-
120-
/// Get or create a [`SourceFile`] for the given path.
121-
///
122-
/// Files are created with an initial revision of 0 and tracked in the [`Database`]'s
123-
/// `DashMap`. The `Arc` ensures cheap cloning while maintaining thread safety.
124-
///
125-
/// ## Thread Safety
126-
///
127-
/// This method is inherently thread-safe despite the check-then-create pattern because
128-
/// it requires `&mut self`, ensuring exclusive access to the Database. Only one thread
129-
/// can call this method at a time due to Rust's ownership rules.
130-
pub fn get_or_create_file(&mut self, path: &PathBuf) -> SourceFile {
131-
if let Some(file_ref) = self.files.get(path) {
132-
// Copy the value (SourceFile is Copy)
133-
// The guard drops automatically, no need for explicit drop
134-
return *file_ref;
135-
}
136-
137-
// File doesn't exist, so we need to create it
138-
let kind = FileKind::from_path(path);
139-
let file = SourceFile::new(self, kind, Arc::from(path.to_string_lossy().as_ref()), 0);
140-
141-
self.files.insert(path.clone(), file);
142-
file
143-
}
144-
145-
/// Check if a file is being tracked without creating it.
146-
///
147-
/// This is primarily used for testing to verify that files have been
148-
/// created without affecting the database state.
149-
pub fn has_file(&self, path: &Path) -> bool {
150-
self.files.contains_key(path)
151-
}
152-
153-
/// Touch a file to mark it as modified, triggering re-evaluation of dependent queries.
154-
///
155-
/// Similar to Unix `touch`, this updates the file's revision number to signal
156-
/// that cached query results depending on this file should be invalidated.
157-
///
158-
/// This is typically called when:
159-
/// - A file is opened in the editor (if it was previously cached from disk)
160-
/// - A file's content is modified
161-
/// - A file's buffer is closed (reverting to disk content)
162-
pub fn touch_file(&mut self, path: &Path) {
163-
// Get the file if it exists
164-
let Some(file_ref) = self.files.get(path) else {
165-
tracing::debug!("File {} not tracked, skipping touch", path.display());
166-
return;
167-
};
168-
let file = *file_ref;
169-
drop(file_ref); // Explicitly drop to release the lock
170-
171-
let current_rev = file.revision(self);
172-
let new_rev = current_rev + 1;
173-
file.set_revision(self).to(new_rev);
174-
175-
tracing::debug!(
176-
"Touched {}: revision {} -> {}",
177-
path.display(),
178-
current_rev,
179-
new_rev
180-
);
181-
}
182-
}
183-
184-
#[salsa::db]
185-
impl salsa::Database for Database {}
186-
187-
#[salsa::db]
188-
impl Db for Database {
189-
fn fs(&self) -> Arc<dyn FileSystem> {
190-
self.fs.clone()
191-
}
192-
193-
fn read_file_content(&self, path: &Path) -> std::io::Result<String> {
194-
self.fs.read_to_string(path)
195-
}
196-
}
197-
19842
/// Represents a single file without storing its content.
19943
///
20044
/// [`SourceFile`] is a Salsa input entity that tracks a file's path, revision, and

crates/djls-workspace/src/fs.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
//! This module provides the [`FileSystem`] trait that abstracts file I/O operations.
44
//! This allows the LSP to work with both real files and in-memory overlays.
55
6-
#[cfg(test)]
76
use std::collections::HashMap;
87
use std::io;
98
use std::path::Path;
10-
#[cfg(test)]
119
use std::path::PathBuf;
1210
use std::sync::Arc;
1311

@@ -19,13 +17,12 @@ pub trait FileSystem: Send + Sync {
1917
fn exists(&self, path: &Path) -> bool;
2018
}
2119

22-
#[cfg(test)]
2320
pub struct InMemoryFileSystem {
2421
files: HashMap<PathBuf, String>,
2522
}
2623

27-
#[cfg(test)]
2824
impl InMemoryFileSystem {
25+
#[must_use]
2926
pub fn new() -> Self {
3027
Self {
3128
files: HashMap::new(),
@@ -37,7 +34,12 @@ impl InMemoryFileSystem {
3734
}
3835
}
3936

40-
#[cfg(test)]
37+
impl Default for InMemoryFileSystem {
38+
fn default() -> Self {
39+
Self::new()
40+
}
41+
}
42+
4143
impl FileSystem for InMemoryFileSystem {
4244
fn read_to_string(&self, path: &Path) -> io::Result<String> {
4345
self.files
@@ -81,7 +83,7 @@ impl FileSystem for OsFileSystem {
8183
/// This ensures consistent behavior across all filesystem operations for
8284
/// buffered files that may not yet be saved to disk.
8385
///
84-
/// This type is used by the [`Database`](crate::db::Database) to ensure all file reads go
86+
/// This type is used by the database implementations to ensure all file reads go
8587
/// through the buffer system first.
8688
pub struct WorkspaceFileSystem {
8789
/// In-memory buffers that take precedence over disk files

crates/djls-workspace/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//! # Key Components
88
//!
99
//! - [`Buffers`] - Thread-safe storage for open documents
10-
//! - [`Database`] - Salsa database for incremental computation
10+
//! - [`Db`] - Database trait for file system access (concrete impl in server crate)
1111
//! - [`TextDocument`] - LSP document representation with efficient indexing
1212
//! - [`FileSystem`] - Abstraction layer for file operations with overlay support
1313
//! - [`paths`] - Consistent URL/path conversion utilities
@@ -24,12 +24,12 @@ mod workspace;
2424
use std::path::Path;
2525

2626
pub use buffers::Buffers;
27-
pub use db::Database;
2827
pub use db::Db;
2928
pub use db::SourceFile;
3029
pub use document::TextDocument;
3130
pub use encoding::PositionEncoding;
3231
pub use fs::FileSystem;
32+
pub use fs::InMemoryFileSystem;
3333
pub use fs::OsFileSystem;
3434
pub use fs::WorkspaceFileSystem;
3535
pub use language::LanguageId;

0 commit comments

Comments
 (0)