@@ -102,9 +102,96 @@ def remove_document(self, identifier: str) -> bool:
102102
103103 return self ._repository .remove_document (document .id or "" )
104104
105- def search (
106- self , query : str , top_k : int = 10
107- ) -> list [Document ]:
105+ def rebuild (self , remove_missing : bool = False ) -> dict :
106+ """Rebuild embeddings and full-text index for all documents"""
107+ self ._ensure_initialized ()
108+
109+ documents = self ._repository .list_documents ()
110+ total_docs = len (documents )
111+ reprocessed = 0
112+ not_found = 0
113+ removed = 0
114+
115+ for doc in documents :
116+ if doc .uri and Path (doc .uri ).exists ():
117+ # File still exists, recreate embeddings
118+ try :
119+ content = FileReader .parse_file (Path (doc .uri ))
120+ doc .content = content
121+
122+ self ._repository .remove_document (doc .id or "" )
123+ processed_doc = self ._engine .process (doc )
124+ self ._repository .add_document (processed_doc )
125+
126+ reprocessed += 1
127+ self ._logger .debug (f"Reprocessed: { doc .uri } " )
128+ except Exception as e :
129+ self ._logger .error (f"Error processing { doc .uri } : { e } " )
130+ not_found += 1
131+ elif doc .uri :
132+ # File not found
133+ not_found += 1
134+ self ._logger .warning (f"File not found: { doc .uri } " )
135+
136+ if remove_missing :
137+ self ._repository .remove_document (doc .id or "" )
138+ removed += 1
139+ self ._logger .info (f"Removed missing document: { doc .uri } " )
140+ else :
141+ # Document without URI (text content)
142+ try :
143+ self ._repository .remove_document (doc .id or "" )
144+ processed_doc = self ._engine .process (doc )
145+ self ._repository .add_document (processed_doc )
146+
147+ reprocessed += 1
148+ self ._logger .debug (f"Reprocessed text document: { doc .content [:20 ]!r} ..." )
149+ except Exception as e :
150+ self ._logger .error (f"Error processing text document { doc .id } : { e } " )
151+
152+ if self .settings .quantize_scan :
153+ self ._engine .quantize ()
154+
155+ return {
156+ "total" : total_docs ,
157+ "reprocessed" : reprocessed ,
158+ "not_found" : not_found ,
159+ "removed" : removed ,
160+ }
161+
162+ def reset (self ) -> bool :
163+ """Reset/clear the entire database by deleting and recreating it"""
164+ db_path = self .settings .db_path
165+
166+ try :
167+ # Close the database connection
168+ self ._conn .close ()
169+
170+ # Delete the database file if it exists
171+ if Path (db_path ).exists ():
172+ Path (db_path ).unlink ()
173+ self ._logger .info (f"Deleted database file: { db_path } " )
174+
175+ # Recreate the database connection and initialize
176+ self ._conn = sqlite3 .connect (db_path )
177+ Database .initialize (self ._conn , self .settings )
178+
179+ # Reinitialize components with new connection
180+ self ._repository = Repository (self ._conn , self .settings )
181+ self ._chunker = Chunker (self ._conn , self .settings )
182+ self ._engine = Engine (self ._conn , self .settings , chunker = self ._chunker )
183+
184+ # Reset ready flag so initialization happens on next use
185+ self .ready = False
186+
187+ self ._logger .info ("Database reset completed successfully" )
188+ return True
189+
190+ except Exception as e :
191+ self ._logger .error (f"Error during database reset: { e } " )
192+ return False
193+
194+ def search (self , query : str , top_k : int = 10 ) -> list [Document ]:
108195 """Search for documents matching the query"""
109196 self ._ensure_initialized ()
110197
0 commit comments