Compare commits

...

3 Commits

Author SHA1 Message Date
semantic-release 7f7ec67cbb chore(release): 0.1.1 [skip ci] 2025-02-07 23:28:29 +00:00
phernandez 04e575041e Merge branch 'main' of github.com:basicmachines-co/basic-memory 2025-02-07 17:23:01 -06:00
phernandez 1fee436bf9 fix: recreate search index on db reset 2025-02-07 17:22:34 -06:00
9 changed files with 30 additions and 50 deletions
+6
View File
@@ -1,6 +1,9 @@
# CHANGELOG
## v0.1.1 (2025-02-07)
## v0.1.0 (2025-02-07)
### Bug Fixes
@@ -17,6 +20,9 @@
- Install fastapi deps after removing basic-foundation
([`51a741e`](https://github.com/basicmachines-co/basic-memory/commit/51a741e7593a1ea0e5eb24e14c70ff61670f9663))
- Recreate search index on db reset
([`1fee436`](https://github.com/basicmachines-co/basic-memory/commit/1fee436bf903a35c9ebb7d87607fc9cc9f5ff6e7))
- Remove basic-foundation from deps
([`b8d0c71`](https://github.com/basicmachines-co/basic-memory/commit/b8d0c7160f29c97cdafe398a7e6a5240473e0c89))
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "basic-memory"
version = "0.1.0"
version = "0.1.1"
description = "Local-first knowledge management combining Zettelkasten with knowledge graphs"
readme = "README.md"
requires-python = ">=3.12.1"
+2 -2
View File
@@ -1,5 +1,5 @@
"""Command module exports."""
from . import init, status, sync, import_memory_json
from . import status, sync, import_memory_json
__all__ = ["init", "status", "sync", "import_memory_json.py"]
__all__ = [ "status", "sync", "import_memory_json.py"]
-38
View File
@@ -1,38 +0,0 @@
"""Initialize command for basic-memory CLI."""
import asyncio
from pathlib import Path
import typer
from loguru import logger
from basic_memory.cli.app import app
from basic_memory.db import engine_session_factory, DatabaseType
from basic_memory.config import config
async def _init(force: bool = False):
"""Initialize the database."""
db_path = config.database_path
if db_path.exists() and not force:
typer.echo(f"Database already exists at {db_path}. Use --force to reinitialize.")
raise typer.Exit(1)
# Create data directory if needed
db_path.parent.mkdir(parents=True, exist_ok=True)
try:
async with engine_session_factory(db_path, db_type=DatabaseType.FILESYSTEM, init=True):
typer.echo(f"Initialized database at {db_path}")
except Exception as e:
logger.error(f"Error initializing database: {e}")
typer.echo(f"Error initializing database: {e}")
raise typer.Exit(1)
@app.command()
def init(
force: bool = typer.Option(False, "--force", "-f", help="Force reinitialization if database exists")
):
"""Initialize a new basic-memory database."""
asyncio.run(_init(force))
+2 -3
View File
@@ -5,11 +5,10 @@ import typer
from loguru import logger
from basic_memory.cli.app import app
from basic_memory.cli.commands.init import init
# Register commands
from basic_memory.cli.commands import init, status, sync
__all__ = ["init", "status", "sync"]
from basic_memory.cli.commands import status, sync
__all__ = ["status", "sync"]
from basic_memory.config import config
+6 -1
View File
@@ -15,6 +15,8 @@ from sqlalchemy.ext.asyncio import (
)
from basic_memory.models import Base, SCHEMA_VERSION
from basic_memory.models.search import CREATE_SEARCH_INDEX
from basic_memory.repository.search_repository import SearchRepository
# Module level state
_engine: Optional[AsyncEngine] = None
@@ -77,7 +79,10 @@ async def init_db() -> None:
await session.execute(text("PRAGMA foreign_keys=ON"))
conn = await session.connection()
await conn.run_sync(Base.metadata.create_all)
# recreate search index
await session.execute(CREATE_SEARCH_INDEX)
await session.commit()
async def drop_db():
@@ -70,6 +70,8 @@ class SearchRepository:
async def init_search_index(self):
"""Create or recreate the search index."""
logger.info("Initializing search index")
async with db.scoped_session(self.session_maker) as session:
await session.execute(CREATE_SEARCH_INDEX)
await session.commit()
@@ -13,6 +13,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from basic_memory import db
from basic_memory.config import ProjectConfig
from basic_memory.models import Base
from basic_memory.repository.search_repository import SearchRepository
async def check_schema_matches_models(session: AsyncSession) -> Tuple[bool, List[str]]:
@@ -127,7 +128,7 @@ class DatabaseService:
for diff in differences:
logger.warning(f" {diff}")
logger.info("Rebuilding database to match current models...")
await self.initialize_db()
await self.initialize_db()
return True
logger.info("Database schema matches models")
+9 -4
View File
@@ -4,6 +4,7 @@ from pathlib import Path
from typing import Dict
from loguru import logger
from sqlalchemy.exc import IntegrityError
from basic_memory import file_utils
from basic_memory.markdown import EntityParser, EntityMarkdown
@@ -153,10 +154,14 @@ class SyncService:
# check we found a link that is not the source
if target_entity and target_entity.id != relation.from_id:
logger.debug(f"Resolved forward reference: {relation.to_name} -> {target_entity.permalink}")
await self.relation_repository.update(relation.id, {
"to_id": target_entity.id,
"to_name": target_entity.title # Update to actual title
})
try:
await self.relation_repository.update(relation.id, {
"to_id": target_entity.id,
"to_name": target_entity.title # Update to actual title
})
except IntegrityError as e:
logger.info(f"Ignoring duplicate relation {relation}")
# update search index
await self.search_service.index_entity(target_entity)