cinchdb 0.1.0__py3-none-any.whl → 0.1.1__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.
@@ -11,6 +11,7 @@ from cinchdb.api.auth import (
11
11
  require_write_permission,
12
12
  require_read_permission,
13
13
  )
14
+ from cinchdb.utils.name_validator import validate_name, InvalidNameError
14
15
 
15
16
 
16
17
  router = APIRouter()
@@ -68,6 +69,12 @@ async def create_database(
68
69
  auth: AuthContext = Depends(require_write_permission),
69
70
  ):
70
71
  """Create a new database."""
72
+ # Validate database name
73
+ try:
74
+ validate_name(request.name, "database")
75
+ except InvalidNameError as e:
76
+ raise HTTPException(status_code=400, detail=str(e))
77
+
71
78
  config = Config(auth.project_dir)
72
79
 
73
80
  # Create database directory structure
@@ -14,6 +14,7 @@ from cinchdb.cli.utils import (
14
14
  set_active_branch,
15
15
  validate_required_arg,
16
16
  )
17
+ from cinchdb.utils.name_validator import validate_name, InvalidNameError
17
18
 
18
19
  app = typer.Typer(help="Branch management commands", invoke_without_command=True)
19
20
  console = Console()
@@ -80,6 +81,14 @@ def create(
80
81
  ):
81
82
  """Create a new branch."""
82
83
  name = validate_required_arg(name, "name", ctx)
84
+
85
+ # Validate branch name
86
+ try:
87
+ validate_name(name, "branch")
88
+ except InvalidNameError as e:
89
+ console.print(f"[red]❌ {e}[/red]")
90
+ raise typer.Exit(1)
91
+
83
92
  config, config_data = get_config_with_data()
84
93
  db_name = config_data.active_database
85
94
  source_branch = source or config_data.active_branch
@@ -12,6 +12,7 @@ from cinchdb.cli.utils import (
12
12
  set_active_branch,
13
13
  validate_required_arg,
14
14
  )
15
+ from cinchdb.utils.name_validator import validate_name, InvalidNameError
15
16
 
16
17
  app = typer.Typer(help="Database management commands", invoke_without_command=True)
17
18
  console = Console()
@@ -64,6 +65,14 @@ def create(
64
65
  ):
65
66
  """Create a new database."""
66
67
  name = validate_required_arg(name, "name", ctx)
68
+
69
+ # Validate database name
70
+ try:
71
+ validate_name(name, "database")
72
+ except InvalidNameError as e:
73
+ console.print(f"[red]❌ {e}[/red]")
74
+ raise typer.Exit(1)
75
+
67
76
  config, config_data = get_config_with_data()
68
77
 
69
78
  # Create database directory structure
@@ -10,6 +10,7 @@ from cinchdb.config import Config
10
10
  from cinchdb.core.path_utils import get_project_root
11
11
  from cinchdb.managers.tenant import TenantManager
12
12
  from cinchdb.cli.utils import get_config_with_data, validate_required_arg
13
+ from cinchdb.utils.name_validator import validate_name, InvalidNameError
13
14
 
14
15
  app = typer.Typer(help="Tenant management commands", invoke_without_command=True)
15
16
  console = Console()
@@ -70,6 +71,14 @@ def create(
70
71
  ):
71
72
  """Create a new tenant."""
72
73
  name = validate_required_arg(name, "name", ctx)
74
+
75
+ # Validate tenant name
76
+ try:
77
+ validate_name(name, "tenant")
78
+ except InvalidNameError as e:
79
+ console.print(f"[red]❌ {e}[/red]")
80
+ raise typer.Exit(1)
81
+
73
82
  config, config_data = get_config_with_data()
74
83
  db_name = config_data.active_database
75
84
  branch_name = config_data.active_branch
@@ -155,6 +164,14 @@ def rename(
155
164
  """Rename a tenant."""
156
165
  old_name = validate_required_arg(old_name, "old_name", ctx)
157
166
  new_name = validate_required_arg(new_name, "new_name", ctx)
167
+
168
+ # Validate new tenant name
169
+ try:
170
+ validate_name(new_name, "tenant")
171
+ except InvalidNameError as e:
172
+ console.print(f"[red]❌ {e}[/red]")
173
+ raise typer.Exit(1)
174
+
158
175
  config, config_data = get_config_with_data()
159
176
  db_name = config_data.active_database
160
177
  branch_name = config_data.active_branch
@@ -13,6 +13,7 @@ from cinchdb.core.path_utils import (
13
13
  get_branch_path,
14
14
  list_branches,
15
15
  )
16
+ from cinchdb.utils.name_validator import validate_name
16
17
 
17
18
 
18
19
  class BranchManager:
@@ -63,7 +64,11 @@ class BranchManager:
63
64
 
64
65
  Raises:
65
66
  ValueError: If source doesn't exist or new branch already exists
67
+ InvalidNameError: If new branch name is invalid
66
68
  """
69
+ # Validate new branch name
70
+ validate_name(new_branch_name, "branch")
71
+
67
72
  # Validate source branch exists
68
73
  if source_branch not in list_branches(self.project_root, self.database):
69
74
  raise ValueError(f"Source branch '{source_branch}' does not exist")
@@ -12,6 +12,7 @@ from cinchdb.core.path_utils import (
12
12
  )
13
13
  from cinchdb.core.connection import DatabaseConnection
14
14
  from cinchdb.core.maintenance import check_maintenance_mode
15
+ from cinchdb.utils.name_validator import validate_name
15
16
 
16
17
 
17
18
  class TenantManager:
@@ -64,8 +65,12 @@ class TenantManager:
64
65
 
65
66
  Raises:
66
67
  ValueError: If tenant already exists
68
+ InvalidNameError: If tenant name is invalid
67
69
  MaintenanceError: If branch is in maintenance mode
68
70
  """
71
+ # Validate tenant name
72
+ validate_name(tenant_name, "tenant")
73
+
69
74
  # Check maintenance mode
70
75
  check_maintenance_mode(self.project_root, self.database, self.branch)
71
76
 
@@ -158,8 +163,12 @@ class TenantManager:
158
163
 
159
164
  Raises:
160
165
  ValueError: If source doesn't exist or target already exists
166
+ InvalidNameError: If target tenant name is invalid
161
167
  MaintenanceError: If branch is in maintenance mode
162
168
  """
169
+ # Validate target tenant name
170
+ validate_name(target_tenant, "tenant")
171
+
163
172
  # Check maintenance mode
164
173
  check_maintenance_mode(self.project_root, self.database, self.branch)
165
174
 
@@ -200,7 +209,11 @@ class TenantManager:
200
209
 
201
210
  Raises:
202
211
  ValueError: If old doesn't exist, new already exists, or trying to rename main
212
+ InvalidNameError: If new tenant name is invalid
203
213
  """
214
+ # Validate new tenant name
215
+ validate_name(new_name, "tenant")
216
+
204
217
  # Can't rename main tenant
205
218
  if old_name == "main":
206
219
  raise ValueError("Cannot rename the main tenant")
cinchdb/models/branch.py CHANGED
@@ -1,8 +1,9 @@
1
1
  """Branch model for CinchDB."""
2
2
 
3
3
  from typing import List, Optional, Dict, Any
4
- from pydantic import Field
4
+ from pydantic import Field, field_validator
5
5
  from .base import CinchDBBaseModel
6
+ from ..utils.name_validator import validate_name
6
7
 
7
8
 
8
9
  class Branch(CinchDBBaseModel):
@@ -21,6 +22,13 @@ class Branch(CinchDBBaseModel):
21
22
  )
22
23
  is_main: bool = Field(default=False, description="Whether this is the main branch")
23
24
 
25
+ @field_validator('name')
26
+ @classmethod
27
+ def validate_name_field(cls, v: str) -> str:
28
+ """Validate branch name meets naming requirements."""
29
+ validate_name(v, "branch")
30
+ return v
31
+
24
32
  def can_delete(self) -> bool:
25
33
  """Check if this branch can be deleted."""
26
34
  return self.name != "main" and not self.is_main
@@ -1,8 +1,9 @@
1
1
  """Database model for CinchDB."""
2
2
 
3
3
  from typing import List, Optional
4
- from pydantic import Field
4
+ from pydantic import Field, field_validator
5
5
  from .base import CinchDBBaseModel
6
+ from ..utils.name_validator import validate_name
6
7
 
7
8
 
8
9
  class Database(CinchDBBaseModel):
@@ -15,6 +16,13 @@ class Database(CinchDBBaseModel):
15
16
  active_branch: str = Field(default="main", description="Currently active branch")
16
17
  description: Optional[str] = Field(default=None, description="Database description")
17
18
 
19
+ @field_validator('name')
20
+ @classmethod
21
+ def validate_name_field(cls, v: str) -> str:
22
+ """Validate database name meets naming requirements."""
23
+ validate_name(v, "database")
24
+ return v
25
+
18
26
  def can_delete(self) -> bool:
19
27
  """Check if this database can be deleted."""
20
28
  return self.name != "main"
cinchdb/models/tenant.py CHANGED
@@ -1,8 +1,9 @@
1
1
  """Tenant model for CinchDB."""
2
2
 
3
3
  from typing import Optional
4
- from pydantic import Field
4
+ from pydantic import Field, field_validator
5
5
  from .base import CinchDBBaseModel
6
+ from ..utils.name_validator import validate_name
6
7
 
7
8
 
8
9
  class Tenant(CinchDBBaseModel):
@@ -14,6 +15,13 @@ class Tenant(CinchDBBaseModel):
14
15
  description: Optional[str] = Field(default=None, description="Tenant description")
15
16
  is_main: bool = Field(default=False, description="Whether this is the main tenant")
16
17
 
18
+ @field_validator('name')
19
+ @classmethod
20
+ def validate_name_field(cls, v: str) -> str:
21
+ """Validate tenant name meets naming requirements."""
22
+ validate_name(v, "tenant")
23
+ return v
24
+
17
25
  def can_delete(self) -> bool:
18
26
  """Check if this tenant can be deleted."""
19
27
  return self.name != "main" and not self.is_main
cinchdb/utils/__init__.py CHANGED
@@ -6,10 +6,20 @@ from cinchdb.utils.sql_validator import (
6
6
  SQLValidationError,
7
7
  SQLOperation
8
8
  )
9
+ from cinchdb.utils.name_validator import (
10
+ validate_name,
11
+ clean_name,
12
+ is_valid_name,
13
+ InvalidNameError
14
+ )
9
15
 
10
16
  __all__ = [
11
17
  "validate_sql_query",
12
18
  "validate_query_safe",
13
19
  "SQLValidationError",
14
- "SQLOperation"
20
+ "SQLOperation",
21
+ "validate_name",
22
+ "clean_name",
23
+ "is_valid_name",
24
+ "InvalidNameError"
15
25
  ]
@@ -0,0 +1,129 @@
1
+ """Name validation utilities for CinchDB entities.
2
+
3
+ Ensures branch, database, and tenant names are safe for filesystem operations
4
+ and follow consistent naming conventions.
5
+ """
6
+
7
+ import re
8
+ from typing import Optional
9
+
10
+
11
+ # Regex pattern for valid names: lowercase letters, numbers, dash, underscore, period
12
+ VALID_NAME_PATTERN = re.compile(r'^[a-z0-9][a-z0-9\-._]*[a-z0-9]$|^[a-z0-9]$')
13
+
14
+ # Reserved names that cannot be used
15
+ RESERVED_NAMES = {'con', 'prn', 'aux', 'nul', 'com1', 'com2', 'com3', 'com4',
16
+ 'com5', 'com6', 'com7', 'com8', 'com9', 'lpt1', 'lpt2',
17
+ 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9'}
18
+
19
+
20
+ class InvalidNameError(ValueError):
21
+ """Raised when a name doesn't meet validation requirements."""
22
+ pass
23
+
24
+
25
+ def validate_name(name: str, entity_type: str = "entity") -> None:
26
+ """Validate that a name meets CinchDB naming requirements.
27
+
28
+ Valid names must:
29
+ - Contain only lowercase letters (a-z), numbers (0-9), dash (-), underscore (_), and period (.)
30
+ - Start and end with alphanumeric characters
31
+ - Be at least 1 character long
32
+ - Not exceed 255 characters (filesystem limit)
33
+ - Not be a reserved name
34
+
35
+ Args:
36
+ name: The name to validate
37
+ entity_type: Type of entity (branch, database, tenant) for error messages
38
+
39
+ Raises:
40
+ InvalidNameError: If the name is invalid
41
+ """
42
+ if not name:
43
+ raise InvalidNameError(f"{entity_type.capitalize()} name cannot be empty")
44
+
45
+ if len(name) > 255:
46
+ raise InvalidNameError(
47
+ f"{entity_type.capitalize()} name cannot exceed 255 characters"
48
+ )
49
+
50
+ # Check for lowercase requirement
51
+ if name != name.lower():
52
+ raise InvalidNameError(
53
+ f"{entity_type.capitalize()} name must be lowercase. "
54
+ f"Use '{name.lower()}' instead of '{name}'"
55
+ )
56
+
57
+ # Check pattern
58
+ if not VALID_NAME_PATTERN.match(name):
59
+ raise InvalidNameError(
60
+ f"Invalid {entity_type} name '{name}'. "
61
+ f"Names must contain only lowercase letters (a-z), numbers (0-9), "
62
+ f"dash (-), underscore (_), and period (.). "
63
+ f"Names must start and end with alphanumeric characters."
64
+ )
65
+
66
+ # Check for consecutive special characters
67
+ if '..' in name or '--' in name or '__' in name or '.-' in name or '-.' in name:
68
+ raise InvalidNameError(
69
+ f"Invalid {entity_type} name '{name}'. "
70
+ f"Names cannot contain consecutive special characters."
71
+ )
72
+
73
+ # Check reserved names
74
+ if name.lower() in RESERVED_NAMES:
75
+ raise InvalidNameError(
76
+ f"'{name}' is a reserved name and cannot be used as a {entity_type} name"
77
+ )
78
+
79
+
80
+ def clean_name(name: str) -> str:
81
+ """Clean a name to make it valid if possible.
82
+
83
+ This performs basic cleaning:
84
+ - Convert to lowercase
85
+ - Replace spaces with dashes
86
+ - Remove invalid characters
87
+
88
+ Args:
89
+ name: The name to clean
90
+
91
+ Returns:
92
+ Cleaned name
93
+
94
+ Note:
95
+ This is a best-effort cleaning. The result should still be validated
96
+ with validate_name() before use.
97
+ """
98
+ # Convert to lowercase
99
+ cleaned = name.lower()
100
+
101
+ # Replace spaces with dashes
102
+ cleaned = cleaned.replace(' ', '-')
103
+
104
+ # Remove invalid characters
105
+ cleaned = re.sub(r'[^a-z0-9\-._]', '', cleaned)
106
+
107
+ # Remove consecutive special characters
108
+ cleaned = re.sub(r'[-._]{2,}', '-', cleaned)
109
+
110
+ # Remove leading/trailing special characters
111
+ cleaned = cleaned.strip('-._')
112
+
113
+ return cleaned
114
+
115
+
116
+ def is_valid_name(name: str) -> bool:
117
+ """Check if a name is valid without raising an exception.
118
+
119
+ Args:
120
+ name: The name to check
121
+
122
+ Returns:
123
+ True if valid, False otherwise
124
+ """
125
+ try:
126
+ validate_name(name)
127
+ return True
128
+ except InvalidNameError:
129
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cinchdb
3
- Version: 0.1.0
3
+ Version: 0.1.1
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
@@ -34,11 +34,11 @@ Description-Content-Type: text/markdown
34
34
 
35
35
  NOTE: CinchDB is in early alpha. This is project to test out an idea. Do not use this in production.
36
36
 
37
- CinchDB is for projects that need to isolate data per-tenant [or even per-user](https://turso.tech/blog/give-each-of-your-users-their-own-sqlite-database-b74445f4) and/or want to test out changes to structure safely in branchces. Plus, queries can be super, super fast because data is separated per tenant so it's <data_size>/<n_tenants> instead of <data_size>
37
+ CinchDB is for projects that need fast queries, data isolated data per-tenant [or even per-user](https://turso.tech/blog/give-each-of-your-users-their-own-sqlite-database-b74445f4), and a branchable database.
38
38
 
39
39
  On a meta level, I made this because I wanted a database structure that I felt comfortable letting AI agents take full control over, safely, and I didn't want to run my own Postgres instance somewhere or pay for it on e.g. Neon - I don't need hyperscaling, I just need super fast queries.
40
40
 
41
- Because it's so lightweight and its only dependencies are FastAPI, pydantic, requests, and Typer, it is super cheap to run on a small VM like from [Fly.io](https://fly.io) and I don't need to SSH into it to connect - I can just store an API key in my local projects.
41
+ Because it's so lightweight and its only dependencies are FastAPI, pydantic, requests, and Typer, it is super cheap to run on a small VM like from [Fly.io](https://fly.io) and I don't need to SSH into it to make changes - I can just store an API key in my local projects and hit the remote instance.
42
42
 
43
43
 
44
44
  ```bash
@@ -11,7 +11,7 @@ cinchdb/api/routers/branches.py,sha256=gEYBDqvwSzt5uSSVDo_mo2ysLfUqaavyDClpzRfYT
11
11
  cinchdb/api/routers/codegen.py,sha256=As9zfBmT7SMx1lrQfRg8TGofcRSOo_r77fCLmxuYkI4,5069
12
12
  cinchdb/api/routers/columns.py,sha256=bWMIInp0Ma9KPp7PHFSr25ROWNKjOkwl9KNc3bQeqMo,8313
13
13
  cinchdb/api/routers/data.py,sha256=rYnh6TwgLArA85AalOydg4txoXD0UWEItAvISuRVTao,14923
14
- cinchdb/api/routers/databases.py,sha256=I6yolh9IoqOoMrhWFFyCDFuKtLGgQGxL2dwEj2FEYeQ,5024
14
+ cinchdb/api/routers/databases.py,sha256=RyetGWqlnW7H7sCB4hOqWIPz-6cmJfI3f3KsIb4IX40,5282
15
15
  cinchdb/api/routers/projects.py,sha256=70nwkXjGiK_pfTr6hv50viOjvQgv5yfC50mEgTByClE,3847
16
16
  cinchdb/api/routers/query.py,sha256=UEtdKLIeo5OjOHfJl3IU3q2o69NOAX0pCyOwb7ivquQ,5120
17
17
  cinchdb/api/routers/tables.py,sha256=Dg0ANMEVHXZyIO-mJBQCnJKfdRORKFqKaunLfJ_cTlo,10403
@@ -21,14 +21,14 @@ cinchdb/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  cinchdb/cli/main.py,sha256=_vBSigtAcYgGBB4qRt2p3ZH8QZ4Osk5rLRe5cOD5ryU,4335
22
22
  cinchdb/cli/utils.py,sha256=Alh3plAiVOGSk_ETqTmh2rYHHFULelizsQOR4e-_KJw,5661
23
23
  cinchdb/cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
24
- cinchdb/cli/commands/branch.py,sha256=8sjumH0XPi8wYNltDH4HXlzRpcr-GHNAaw8zzmIYYus,17622
24
+ cinchdb/cli/commands/branch.py,sha256=pNltZ2yyUuVGG1D_x5Rmr3lcyr0ibC98xEQevTtt0Q0,17890
25
25
  cinchdb/cli/commands/codegen.py,sha256=WsRWmXNTDuaLPyECW5psXM9zOQnKHpUiv8BJnBAjMII,6189
26
26
  cinchdb/cli/commands/column.py,sha256=CQJZ-mkv_qaBnZDrNhKaunUdxVyz5zmbsZakUnz5-dg,11634
27
- cinchdb/cli/commands/database.py,sha256=qn1i0o_sRVID-yjIPYib1l9_7Qun0zzKvsqdLH1-Mcw,6597
27
+ cinchdb/cli/commands/database.py,sha256=TxJ3xZfAb7zyq2NrnL1PPYQWENsjMYq_GjuS3J0yuyw,6865
28
28
  cinchdb/cli/commands/query.py,sha256=yce0rvp3WQCzFA08cP1DoP2Yir4NSYxX1XxXPmmo3lM,5120
29
29
  cinchdb/cli/commands/remote.py,sha256=LecazBIlEAx8J85vONDrQyy3OEYkmYGCeTGS-c0PD1Y,4500
30
30
  cinchdb/cli/commands/table.py,sha256=ApDcn-iJ-Cjsf4ubQh8UVNBxJmhLQ_O2FxQeBRk6xMI,10511
31
- cinchdb/cli/commands/tenant.py,sha256=p6uReHyYh2Hl6ayWMHCTY_wUARcUHSl0n4Y20Nsi3gA,5752
31
+ cinchdb/cli/commands/tenant.py,sha256=G9jxj8rrSfXJqYYi6Lls21wDShYr1aDgj_vffbjG-j4,6223
32
32
  cinchdb/cli/commands/view.py,sha256=ZmS1IW7idzzHAXmgVyY3C4IQRo7toHb6fHNFY_tQJjI,6385
33
33
  cinchdb/cli/handlers/__init__.py,sha256=f2f-Cc96rSBLbVsiIbf-b4pZCKZoHfmhNEvnZ0OurRs,131
34
34
  cinchdb/cli/handlers/codegen_handler.py,sha256=i5we_AbiUW3zfO6pIKWxvtO8OvOqz3H__4xPmTLEuQM,6524
@@ -38,7 +38,7 @@ cinchdb/core/database.py,sha256=QDz3imoCvrWAA4zLuYaM6lUNRKDQWrYAQPfIJyZkgyw,1798
38
38
  cinchdb/core/maintenance.py,sha256=PAgrSL7Cj9p3rKHV0h_L7gupN6nLD0-5eQpJZNiqyEs,2097
39
39
  cinchdb/core/path_utils.py,sha256=J2UEu1X_NFOqDamcsrPrC7ZitGTg9Y-HFjmx4sHf5j8,3806
40
40
  cinchdb/managers/__init__.py,sha256=ic61ZUdsg-muq0ETYO6fuZRQWF4j7l920PthTkt2QrE,808
41
- cinchdb/managers/branch.py,sha256=4rsusRQlLNfM55IS2dzosnVju7rbeJdaR9jcMPM9Bl8,5165
41
+ cinchdb/managers/branch.py,sha256=uj_ReZF9lmXgwn0DhAh6xCrE2LieG1CVHHEeOzhnr1E,5373
42
42
  cinchdb/managers/change_applier.py,sha256=cHPhPgbJ9jeyrb6lkfRyumS8IHat0HiWfwZh-n7ButA,14310
43
43
  cinchdb/managers/change_comparator.py,sha256=08pwybpSt36cFwhZRSIkHynvFMUaLKEVwa8Ajn_R9yQ,6862
44
44
  cinchdb/managers/change_tracker.py,sha256=U93BPnuGv8xSaO5qr_y5Q8ppKrVXygozdp5zUvLUqwg,5054
@@ -48,21 +48,22 @@ cinchdb/managers/data.py,sha256=4wn9fxFPhrDvtudc1pdQmr0vf0w9H92VrzAIVyTXFCY,1540
48
48
  cinchdb/managers/merge_manager.py,sha256=R8S2hLkLJg4hLDpeJTzjVkduZgqPOjXtYgOSJhTXXrE,15690
49
49
  cinchdb/managers/query.py,sha256=c91J5FAR-Ze5Zy5HNEVIPvc8yuxe-xIv6XHH-lmdB2k,7307
50
50
  cinchdb/managers/table.py,sha256=9Z_RJxZ9fMm_gYbmHXGG0-xZ0cNia1y5tusnydW66_U,13155
51
- cinchdb/managers/tenant.py,sha256=sqLdfIqNkMBzM1b1iOYhVfgJqxhfzzjn5uoXOcP2bJg,8251
51
+ cinchdb/managers/tenant.py,sha256=ZMx9H8XHua512fFRK2xBxa3xjqJJ551xp399mGm16s4,8750
52
52
  cinchdb/managers/view.py,sha256=v9gYtRufZyxywPKLGvIjvlUXcxYh9CLRArefu9QX6zk,7809
53
53
  cinchdb/models/__init__.py,sha256=382OuS0BaKPA71GjqNW5lfVhtUYqmcMlLRin7HPi6XI,602
54
54
  cinchdb/models/base.py,sha256=7j4rlFTP5K9ZuF8vxwC7lMFEaL7O90NJ47Ig5i7ubcw,1320
55
- cinchdb/models/branch.py,sha256=nam76NJbLHHLbcQF2SaVADH7s2jrlFRGGRt_PDNhkwc,904
55
+ cinchdb/models/branch.py,sha256=vKw7rtwxKSpgXAHBKwf5Fkd4LjtiZcfDwtAqeq1LoBE,1180
56
56
  cinchdb/models/change.py,sha256=YpBWdI6yMT3uucd8duET9s75xr5JUWJqurkkyTlXPlk,1449
57
- cinchdb/models/database.py,sha256=kIlvIoGlN3Hhk5UDHo2gKT9g4GCGfKHDL0cpVtoimc8,691
57
+ cinchdb/models/database.py,sha256=Z_XZwBfjcZe7x6IsFD5fgD3a-k5ESzRoVukMlPpTIek,971
58
58
  cinchdb/models/project.py,sha256=6GMXUZUsEIebqQJgRXIthWzpWKuNNmJ3drgI1vFDrMo,644
59
59
  cinchdb/models/table.py,sha256=s6BGoHDuA-yzqQL9papRTVT2WcHjuY-SnoanGFDlFIE,2793
60
- cinchdb/models/tenant.py,sha256=Y7_J_dFwwnXPM0EgF3J_g2M3guycfjqpdGEl03LG7p0,691
60
+ cinchdb/models/tenant.py,sha256=Jut8qoHX79OG3zDNXAdDqzGmlGiV8trGe3t5kXbFt1E,967
61
61
  cinchdb/models/view.py,sha256=q6j-jYzFJuhRJO87rKt6Uv8hOizHQx8xwoPKoH6XnNY,530
62
- cinchdb/utils/__init__.py,sha256=9VXzZBggOfzdj8DTdGBqqOxJzBAm-WS1M_zeToF1fgs,282
62
+ cinchdb/utils/__init__.py,sha256=1mBU1H2C9urYA8Z_v5BTdAfDe0mQ6GMAK0AM3zRPv5k,487
63
+ cinchdb/utils/name_validator.py,sha256=sOeufsnIH2b7I9C3xUkQdmNv8NgnReVb6BVJkczwbeE,3955
63
64
  cinchdb/utils/sql_validator.py,sha256=7STxsVO7bD4gZ8mfimQSt4_Yfckw62plUS_X_xJ48Vo,5427
64
- cinchdb-0.1.0.dist-info/METADATA,sha256=s9s1w2lUNuc2fQ-SqdHEcD2j6rzDjUhrxw8ZednTI6A,5998
65
- cinchdb-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
66
- cinchdb-0.1.0.dist-info/entry_points.txt,sha256=Zzlwp632_jT5OZBkrewvH3-RWUJ9E5vD_BNme6J-A1I,83
67
- cinchdb-0.1.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
68
- cinchdb-0.1.0.dist-info/RECORD,,
65
+ cinchdb-0.1.1.dist-info/METADATA,sha256=45UJWJpH-sxzqdK1Z48065DJuFtEWv44KcQqp-ohe4c,5878
66
+ cinchdb-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
67
+ cinchdb-0.1.1.dist-info/entry_points.txt,sha256=Zzlwp632_jT5OZBkrewvH3-RWUJ9E5vD_BNme6J-A1I,83
68
+ cinchdb-0.1.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
69
+ cinchdb-0.1.1.dist-info/RECORD,,