cinchdb 0.1.7__tar.gz → 0.1.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. {cinchdb-0.1.7 → cinchdb-0.1.8}/PKG-INFO +1 -1
  2. {cinchdb-0.1.7 → cinchdb-0.1.8}/pyproject.toml +1 -1
  3. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/core/database.py +8 -4
  4. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/index.py +17 -13
  5. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/table.py +21 -3
  6. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/tenant.py +4 -0
  7. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/__init__.py +2 -1
  8. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/table.py +10 -0
  9. {cinchdb-0.1.7 → cinchdb-0.1.8}/.gitignore +0 -0
  10. {cinchdb-0.1.7 → cinchdb-0.1.8}/LICENSE +0 -0
  11. {cinchdb-0.1.7 → cinchdb-0.1.8}/README.md +0 -0
  12. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/__init__.py +0 -0
  13. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/__main__.py +0 -0
  14. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/__init__.py +0 -0
  15. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/__init__.py +0 -0
  16. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/branch.py +0 -0
  17. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/codegen.py +0 -0
  18. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/column.py +0 -0
  19. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/database.py +0 -0
  20. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/index.py +0 -0
  21. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/query.py +0 -0
  22. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/remote.py +0 -0
  23. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/table.py +0 -0
  24. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/tenant.py +0 -0
  25. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/commands/view.py +0 -0
  26. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/handlers/__init__.py +0 -0
  27. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/handlers/codegen_handler.py +0 -0
  28. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/main.py +0 -0
  29. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/cli/utils.py +0 -0
  30. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/config.py +0 -0
  31. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/core/__init__.py +0 -0
  32. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/core/connection.py +0 -0
  33. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/core/initializer.py +0 -0
  34. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/core/maintenance.py +0 -0
  35. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/core/path_utils.py +0 -0
  36. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/__init__.py +0 -0
  37. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/branch.py +0 -0
  38. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/change_applier.py +0 -0
  39. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/change_comparator.py +0 -0
  40. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/change_tracker.py +0 -0
  41. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/codegen.py +0 -0
  42. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/column.py +0 -0
  43. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/data.py +0 -0
  44. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/merge_manager.py +0 -0
  45. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/query.py +0 -0
  46. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/managers/view.py +0 -0
  47. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/base.py +0 -0
  48. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/branch.py +0 -0
  49. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/change.py +0 -0
  50. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/database.py +0 -0
  51. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/project.py +0 -0
  52. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/tenant.py +0 -0
  53. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/models/view.py +0 -0
  54. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/utils/__init__.py +0 -0
  55. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/utils/name_validator.py +0 -0
  56. {cinchdb-0.1.7 → cinchdb-0.1.8}/src/cinchdb/utils/sql_validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cinchdb
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: A Git-like SQLite database management system with branching and multi-tenancy
5
5
  Project-URL: Homepage, https://github.com/russellromney/cinchdb
6
6
  Project-URL: Documentation, https://russellromney.github.io/cinchdb
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cinchdb"
3
- version = "0.1.7"
3
+ version = "0.1.8"
4
4
  description = "A Git-like SQLite database management system with branching and multi-tenancy"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -507,8 +507,12 @@ class CinchDB:
507
507
  # Named index
508
508
  db.create_index("products", ["category", "price"], name="idx_category_price")
509
509
  """
510
+ # Convert parameters to Index model for validation
511
+ from cinchdb.models import Index
512
+ index = Index(columns=columns, name=name, unique=unique)
513
+
510
514
  if self.is_local:
511
- return self.indexes.create_index(table, columns, name, unique)
515
+ return self.indexes.create_index(table, index.columns, index.name, index.unique)
512
516
  else:
513
517
  # Remote index creation
514
518
  result = self._make_request(
@@ -516,9 +520,9 @@ class CinchDB:
516
520
  "/indexes",
517
521
  json={
518
522
  "table": table,
519
- "columns": columns,
520
- "name": name,
521
- "unique": unique,
523
+ "columns": index.columns,
524
+ "name": index.name,
525
+ "unique": index.unique,
522
526
  },
523
527
  )
524
528
  return result.get("name")
@@ -52,14 +52,18 @@ class IndexManager:
52
52
  Raises:
53
53
  ValueError: If table doesn't exist or columns are invalid
54
54
  """
55
- if not columns:
55
+ # Convert parameters to Index model for validation
56
+ from cinchdb.models import Index
57
+ index = Index(columns=columns, name=name, unique=unique)
58
+
59
+ if not index.columns:
56
60
  raise ValueError("At least one column must be specified for the index")
57
61
 
58
62
  # Generate index name if not provided
59
- if not name:
60
- column_str = "_".join(columns)
61
- unique_prefix = "uniq_" if unique else "idx_"
62
- name = f"{unique_prefix}{table}_{column_str}"
63
+ if not index.name:
64
+ column_str = "_".join(index.columns)
65
+ unique_prefix = "uniq_" if index.unique else "idx_"
66
+ index.name = f"{unique_prefix}{table}_{column_str}"
63
67
 
64
68
  # Get connection to main tenant database (indexes are branch-level)
65
69
  db_path = get_tenant_db_path(
@@ -79,18 +83,18 @@ class IndexManager:
79
83
  result = conn.execute(f"PRAGMA table_info({table})")
80
84
  existing_columns = {row[1] for row in result.fetchall()}
81
85
 
82
- invalid_columns = set(columns) - existing_columns
86
+ invalid_columns = set(index.columns) - existing_columns
83
87
  if invalid_columns:
84
88
  raise ValueError(
85
89
  f"Columns {invalid_columns} do not exist in table '{table}'"
86
90
  )
87
91
 
88
92
  # Build and execute CREATE INDEX statement
89
- unique_clause = "UNIQUE " if unique else ""
93
+ unique_clause = "UNIQUE " if index.unique else ""
90
94
  if_not_exists_clause = "IF NOT EXISTS " if if_not_exists else ""
91
- column_list = ", ".join(columns)
95
+ column_list = ", ".join(index.columns)
92
96
 
93
- sql = f"CREATE {unique_clause}INDEX {if_not_exists_clause}{name} ON {table} ({column_list})"
97
+ sql = f"CREATE {unique_clause}INDEX {if_not_exists_clause}{index.name} ON {table} ({column_list})"
94
98
 
95
99
  try:
96
100
  result = conn.execute(sql)
@@ -98,18 +102,18 @@ class IndexManager:
98
102
  except sqlite3.Error as e:
99
103
  if "already exists" in str(e):
100
104
  if not if_not_exists:
101
- raise ValueError(f"Index '{name}' already exists")
105
+ raise ValueError(f"Index '{index.name}' already exists")
102
106
  else:
103
107
  raise
104
108
 
105
109
  # Track the change
106
110
  self._track_change(
107
111
  ChangeType.CREATE_INDEX,
108
- name,
109
- {"table": table, "columns": columns, "unique": unique}
112
+ index.name,
113
+ {"table": table, "columns": index.columns, "unique": index.unique}
110
114
  )
111
115
 
112
- return name
116
+ return index.name
113
117
 
114
118
  def drop_index(self, name: str, if_exists: bool = True) -> None:
115
119
  """Drop an index.
@@ -1,9 +1,12 @@
1
1
  """Table management for CinchDB."""
2
2
 
3
3
  from pathlib import Path
4
- from typing import List
4
+ from typing import List, Optional, TYPE_CHECKING
5
5
 
6
6
  from cinchdb.models import Table, Column, Change, ChangeType
7
+
8
+ if TYPE_CHECKING:
9
+ from cinchdb.models import Index
7
10
  from cinchdb.core.connection import DatabaseConnection
8
11
  from cinchdb.core.path_utils import get_tenant_db_path
9
12
  from cinchdb.core.maintenance import check_maintenance_mode
@@ -61,12 +64,13 @@ class TableManager:
61
64
 
62
65
  return tables
63
66
 
64
- def create_table(self, table_name: str, columns: List[Column]) -> Table:
65
- """Create a new table with optional foreign key constraints.
67
+ def create_table(self, table_name: str, columns: List[Column], indexes: Optional[List["Index"]] = None) -> Table:
68
+ """Create a new table with optional foreign key constraints and indexes.
66
69
 
67
70
  Args:
68
71
  table_name: Name of the table
69
72
  columns: List of Column objects defining the schema
73
+ indexes: Optional list of Index objects to create on the table
70
74
 
71
75
  Returns:
72
76
  Created Table object
@@ -168,6 +172,20 @@ class TableManager:
168
172
  applier = ChangeApplier(self.project_root, self.database, self.branch)
169
173
  applier.apply_change(change.id)
170
174
 
175
+ # Create indexes if specified
176
+ if indexes:
177
+ from cinchdb.managers.index import IndexManager
178
+ index_manager = IndexManager(self.project_root, self.database, self.branch)
179
+
180
+ for index in indexes:
181
+ index_manager.create_index(
182
+ table=table_name,
183
+ columns=index.columns,
184
+ name=index.name,
185
+ unique=index.unique,
186
+ if_not_exists=True
187
+ )
188
+
171
189
  # Return the created table
172
190
  return Table(
173
191
  name=table_name,
@@ -104,6 +104,10 @@ class TenantManager:
104
104
  conn.execute(f"DELETE FROM {table}")
105
105
 
106
106
  conn.commit()
107
+
108
+ # Open a new connection to vacuum the database
109
+ with DatabaseConnection(new_db_path) as conn:
110
+ conn.execute("VACUUM")
107
111
 
108
112
  return Tenant(
109
113
  name=tenant_name,
@@ -5,7 +5,7 @@ from .project import Project
5
5
  from .database import Database
6
6
  from .branch import Branch
7
7
  from .tenant import Tenant
8
- from .table import Table, Column, ColumnType, ForeignKeyRef, ForeignKeyAction
8
+ from .table import Table, Column, ColumnType, ForeignKeyRef, ForeignKeyAction, Index
9
9
  from .view import View
10
10
  from .change import Change, ChangeType
11
11
 
@@ -21,6 +21,7 @@ __all__ = [
21
21
  "ColumnType",
22
22
  "ForeignKeyRef",
23
23
  "ForeignKeyAction",
24
+ "Index",
24
25
  "View",
25
26
  "Change",
26
27
  "ChangeType",
@@ -27,6 +27,16 @@ class ForeignKeyRef(BaseModel):
27
27
  )
28
28
 
29
29
 
30
+ class Index(BaseModel):
31
+ """Index specification for table columns."""
32
+
33
+ model_config = ConfigDict(extra="forbid")
34
+
35
+ columns: List[str] = Field(description="Column names to index")
36
+ name: Optional[str] = Field(default=None, description="Index name")
37
+ unique: bool = Field(default=False, description="Create unique index")
38
+
39
+
30
40
  class Column(BaseModel):
31
41
  """Represents a column in a table."""
32
42
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes