cinchdb 0.1.9__py3-none-any.whl → 0.1.11__py3-none-any.whl

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.
@@ -153,8 +153,7 @@ class ColumnManager:
153
153
  col_defs = []
154
154
  for col in new_columns:
155
155
  col_def = f"{col.name} {col.type}"
156
- if col.primary_key:
157
- col_def += " PRIMARY KEY"
156
+ # Primary keys are handled at table creation, not as a column attribute
158
157
  if not col.nullable:
159
158
  col_def += " NOT NULL"
160
159
  if col.default is not None:
@@ -326,7 +325,6 @@ class ColumnManager:
326
325
  type=col.type,
327
326
  nullable=col.nullable,
328
327
  default=col.default,
329
- primary_key=col.primary_key,
330
328
  unique=col.unique,
331
329
  )
332
330
  new_columns.append(new_col)
@@ -339,8 +337,7 @@ class ColumnManager:
339
337
  col_defs = []
340
338
  for col in new_columns:
341
339
  col_def = f"{col.name} {col.type}"
342
- if col.primary_key:
343
- col_def += " PRIMARY KEY"
340
+ # Primary keys are handled at table creation, not as a column attribute
344
341
  if not col.nullable:
345
342
  col_def += " NOT NULL"
346
343
  if col.default is not None:
@@ -397,7 +394,6 @@ class ColumnManager:
397
394
  type=col.type,
398
395
  nullable=col.nullable,
399
396
  default=col.default,
400
- primary_key=col.primary_key,
401
397
  unique=col.unique,
402
398
  )
403
399
  new_columns.append(new_col)
@@ -410,8 +406,7 @@ class ColumnManager:
410
406
  col_defs = []
411
407
  for col in new_columns:
412
408
  col_def = f"{col.name} {col.type}"
413
- if col.primary_key:
414
- col_def += " PRIMARY KEY"
409
+ # Primary keys are handled at table creation, not as a column attribute
415
410
  if not col.nullable:
416
411
  col_def += " NOT NULL"
417
412
  if col.default is not None:
@@ -512,8 +507,7 @@ class ColumnManager:
512
507
  col_defs = []
513
508
  for col in existing_columns:
514
509
  col_def = f"{col.name} {col.type}"
515
- if col.primary_key:
516
- col_def += " PRIMARY KEY"
510
+ # Primary keys are handled at table creation, not as a column attribute
517
511
  # Apply nullable change to target column
518
512
  if col.name == column_name:
519
513
  if not nullable:
cinchdb/managers/query.py CHANGED
@@ -8,6 +8,7 @@ from pydantic import BaseModel, ValidationError
8
8
  from cinchdb.core.connection import DatabaseConnection
9
9
  from cinchdb.core.path_utils import get_tenant_db_path
10
10
  from cinchdb.utils import validate_query_safe
11
+ from cinchdb.managers.tenant import TenantManager
11
12
 
12
13
  T = TypeVar("T", bound=BaseModel)
13
14
 
@@ -30,7 +31,24 @@ class QueryManager:
30
31
  self.database = database
31
32
  self.branch = branch
32
33
  self.tenant = tenant
33
- self.db_path = get_tenant_db_path(project_root, database, branch, tenant)
34
+ # Initialize tenant manager for lazy tenant handling
35
+ self.tenant_manager = TenantManager(project_root, database, branch)
36
+
37
+ def _is_write_query(self, sql: str) -> bool:
38
+ """Check if a SQL query is a write operation.
39
+
40
+ Args:
41
+ sql: SQL query string
42
+
43
+ Returns:
44
+ True if query performs writes, False otherwise
45
+ """
46
+ sql_upper = sql.strip().upper()
47
+ write_keywords = [
48
+ "INSERT", "UPDATE", "DELETE", "CREATE", "ALTER", "DROP",
49
+ "TRUNCATE", "REPLACE", "MERGE"
50
+ ]
51
+ return any(sql_upper.startswith(keyword) for keyword in write_keywords)
34
52
 
35
53
  def execute(
36
54
  self,
@@ -62,7 +80,12 @@ class QueryManager:
62
80
  "execute() can only be used with SELECT queries. Use execute_non_query() for INSERT/UPDATE/DELETE operations."
63
81
  )
64
82
 
65
- with DatabaseConnection(self.db_path) as conn:
83
+ # Get appropriate database path based on operation type (read for SELECT)
84
+ db_path = self.tenant_manager.get_tenant_db_path_for_operation(
85
+ self.tenant, is_write=False
86
+ )
87
+
88
+ with DatabaseConnection(db_path) as conn:
66
89
  cursor = conn.execute(sql, params)
67
90
  rows = cursor.fetchall()
68
91
  return [dict(row) for row in rows]
@@ -187,7 +210,12 @@ class QueryManager:
187
210
  if not skip_validation:
188
211
  validate_query_safe(sql)
189
212
 
190
- with DatabaseConnection(self.db_path) as conn:
213
+ # Get appropriate database path based on operation type (write for non-SELECT)
214
+ db_path = self.tenant_manager.get_tenant_db_path_for_operation(
215
+ self.tenant, is_write=True
216
+ )
217
+
218
+ with DatabaseConnection(db_path) as conn:
191
219
  cursor = conn.execute(sql, params)
192
220
  affected_rows = cursor.rowcount
193
221
  conn.commit()
@@ -208,7 +236,15 @@ class QueryManager:
208
236
  """
209
237
  total_affected = 0
210
238
 
211
- with DatabaseConnection(self.db_path) as conn:
239
+ # Determine if this is a write operation
240
+ is_write = self._is_write_query(sql)
241
+
242
+ # Get appropriate database path
243
+ db_path = self.tenant_manager.get_tenant_db_path_for_operation(
244
+ self.tenant, is_write=is_write
245
+ )
246
+
247
+ with DatabaseConnection(db_path) as conn:
212
248
  try:
213
249
  for params in params_list:
214
250
  cursor = conn.execute(sql, params)
cinchdb/managers/table.py CHANGED
@@ -124,9 +124,9 @@ class TableManager:
124
124
  fk_constraint += f" ON UPDATE {fk.on_update}"
125
125
  foreign_key_constraints.append(fk_constraint)
126
126
 
127
- # Build automatic columns
127
+ # Build automatic columns (id is always the primary key)
128
128
  auto_columns = [
129
- Column(name="id", type="TEXT", primary_key=True, nullable=False),
129
+ Column(name="id", type="TEXT", nullable=False),
130
130
  Column(name="created_at", type="TEXT", nullable=False),
131
131
  Column(name="updated_at", type="TEXT", nullable=True),
132
132
  ]
@@ -139,13 +139,14 @@ class TableManager:
139
139
  for col in all_columns:
140
140
  col_def = f"{col.name} {col.type}"
141
141
 
142
- if col.primary_key:
142
+ # id column is always the primary key
143
+ if col.name == "id":
143
144
  col_def += " PRIMARY KEY"
144
145
  if not col.nullable:
145
146
  col_def += " NOT NULL"
146
147
  if col.default is not None:
147
148
  col_def += f" DEFAULT {col.default}"
148
- if col.unique and not col.primary_key:
149
+ if col.unique and col.name != "id": # id is already unique via PRIMARY KEY
149
150
  col_def += " UNIQUE"
150
151
 
151
152
  sql_parts.append(col_def)
@@ -261,7 +262,7 @@ class TableManager:
261
262
  type=col_type,
262
263
  nullable=(row["notnull"] == 0),
263
264
  default=row["dflt_value"],
264
- primary_key=(row["pk"] == 1),
265
+ # Note: primary_key info not needed - 'id' is always the primary key
265
266
  foreign_key=foreign_key,
266
267
  )
267
268
  columns.append(column)
@@ -339,7 +340,8 @@ class TableManager:
339
340
  for col in source.columns:
340
341
  col_def = f"{col.name} {col.type}"
341
342
 
342
- if col.primary_key:
343
+ # id column is always the primary key
344
+ if col.name == "id":
343
345
  col_def += " PRIMARY KEY"
344
346
  if not col.nullable:
345
347
  col_def += " NOT NULL"