cinchdb 0.1.3__py3-none-any.whl → 0.1.4__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.
cinchdb/models/table.py CHANGED
@@ -14,18 +14,16 @@ ForeignKeyAction = Literal["CASCADE", "SET NULL", "RESTRICT", "NO ACTION"]
14
14
 
15
15
  class ForeignKeyRef(BaseModel):
16
16
  """Foreign key reference specification."""
17
-
17
+
18
18
  model_config = ConfigDict(extra="forbid")
19
-
19
+
20
20
  table: str = Field(description="Referenced table name")
21
21
  column: str = Field(default="id", description="Referenced column name")
22
22
  on_delete: ForeignKeyAction = Field(
23
- default="RESTRICT",
24
- description="Action on delete of referenced row"
23
+ default="RESTRICT", description="Action on delete of referenced row"
25
24
  )
26
25
  on_update: ForeignKeyAction = Field(
27
- default="RESTRICT",
28
- description="Action on update of referenced row"
26
+ default="RESTRICT", description="Action on update of referenced row"
29
27
  )
30
28
 
31
29
 
@@ -47,8 +45,7 @@ class Column(BaseModel):
47
45
  )
48
46
  unique: bool = Field(default=False, description="Whether values must be unique")
49
47
  foreign_key: Optional[ForeignKeyRef] = Field(
50
- default=None,
51
- description="Foreign key constraint specification"
48
+ default=None, description="Foreign key constraint specification"
52
49
  )
53
50
 
54
51
 
cinchdb/models/tenant.py CHANGED
@@ -15,7 +15,7 @@ class Tenant(CinchDBBaseModel):
15
15
  description: Optional[str] = Field(default=None, description="Tenant description")
16
16
  is_main: bool = Field(default=False, description="Whether this is the main tenant")
17
17
 
18
- @field_validator('name')
18
+ @field_validator("name")
19
19
  @classmethod
20
20
  def validate_name_field(cls, v: str) -> str:
21
21
  """Validate tenant name meets naming requirements."""
cinchdb/utils/__init__.py CHANGED
@@ -4,13 +4,13 @@ from cinchdb.utils.sql_validator import (
4
4
  validate_sql_query,
5
5
  validate_query_safe,
6
6
  SQLValidationError,
7
- SQLOperation
7
+ SQLOperation,
8
8
  )
9
9
  from cinchdb.utils.name_validator import (
10
10
  validate_name,
11
11
  clean_name,
12
12
  is_valid_name,
13
- InvalidNameError
13
+ InvalidNameError,
14
14
  )
15
15
 
16
16
  __all__ = [
@@ -19,7 +19,7 @@ __all__ = [
19
19
  "SQLValidationError",
20
20
  "SQLOperation",
21
21
  "validate_name",
22
- "clean_name",
22
+ "clean_name",
23
23
  "is_valid_name",
24
- "InvalidNameError"
25
- ]
24
+ "InvalidNameError",
25
+ ]
@@ -5,55 +5,76 @@ and follow consistent naming conventions.
5
5
  """
6
6
 
7
7
  import re
8
- from typing import Optional
9
8
 
10
9
 
11
10
  # 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]$')
11
+ VALID_NAME_PATTERN = re.compile(r"^[a-z0-9][a-z0-9\-_\.]*[a-z0-9]$|^[a-z0-9]$")
13
12
 
14
13
  # 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'}
14
+ RESERVED_NAMES = {
15
+ "con",
16
+ "prn",
17
+ "aux",
18
+ "nul",
19
+ "com1",
20
+ "com2",
21
+ "com3",
22
+ "com4",
23
+ "com5",
24
+ "com6",
25
+ "com7",
26
+ "com8",
27
+ "com9",
28
+ "lpt1",
29
+ "lpt2",
30
+ "lpt3",
31
+ "lpt4",
32
+ "lpt5",
33
+ "lpt6",
34
+ "lpt7",
35
+ "lpt8",
36
+ "lpt9",
37
+ }
18
38
 
19
39
 
20
40
  class InvalidNameError(ValueError):
21
41
  """Raised when a name doesn't meet validation requirements."""
42
+
22
43
  pass
23
44
 
24
45
 
25
46
  def validate_name(name: str, entity_type: str = "entity") -> None:
26
47
  """Validate that a name meets CinchDB naming requirements.
27
-
48
+
28
49
  Valid names must:
29
50
  - Contain only lowercase letters (a-z), numbers (0-9), dash (-), and underscore (_)
30
51
  - Start and end with alphanumeric characters
31
52
  - Be at least 1 character long
32
53
  - Not exceed 255 characters (filesystem limit)
33
54
  - Not be a reserved name
34
-
55
+
35
56
  Args:
36
57
  name: The name to validate
37
58
  entity_type: Type of entity (branch, database, tenant) for error messages
38
-
59
+
39
60
  Raises:
40
61
  InvalidNameError: If the name is invalid
41
62
  """
42
63
  if not name:
43
64
  raise InvalidNameError(f"{entity_type.capitalize()} name cannot be empty")
44
-
65
+
45
66
  if len(name) > 255:
46
67
  raise InvalidNameError(
47
68
  f"{entity_type.capitalize()} name cannot exceed 255 characters"
48
69
  )
49
-
70
+
50
71
  # Check for lowercase requirement
51
72
  if name != name.lower():
52
73
  raise InvalidNameError(
53
74
  f"{entity_type.capitalize()} name must be lowercase. "
54
75
  f"Use '{name.lower()}' instead of '{name}'"
55
76
  )
56
-
77
+
57
78
  # Check pattern
58
79
  if not VALID_NAME_PATTERN.match(name):
59
80
  raise InvalidNameError(
@@ -62,14 +83,24 @@ def validate_name(name: str, entity_type: str = "entity") -> None:
62
83
  f"dash (-), underscore (_), and period (.). "
63
84
  f"Names must start and end with alphanumeric characters."
64
85
  )
65
-
86
+
66
87
  # Check for consecutive special characters
67
- if '--' in name or '__' in name or '-_' in name or '_-' in name or '..' in name or '.-' in name or '-.' in name or '._' in name or '_.' in name:
88
+ if (
89
+ "--" in name
90
+ or "__" in name
91
+ or "-_" in name
92
+ or "_-" in name
93
+ or ".." in name
94
+ or ".-" in name
95
+ or "-." in name
96
+ or "._" in name
97
+ or "_." in name
98
+ ):
68
99
  raise InvalidNameError(
69
100
  f"Invalid {entity_type} name '{name}'. "
70
101
  f"Names cannot contain consecutive special characters."
71
102
  )
72
-
103
+
73
104
  # Check reserved names
74
105
  if name.lower() in RESERVED_NAMES:
75
106
  raise InvalidNameError(
@@ -79,46 +110,46 @@ def validate_name(name: str, entity_type: str = "entity") -> None:
79
110
 
80
111
  def clean_name(name: str) -> str:
81
112
  """Clean a name to make it valid if possible.
82
-
113
+
83
114
  This performs basic cleaning:
84
115
  - Convert to lowercase
85
116
  - Replace spaces with dashes
86
117
  - Remove invalid characters
87
-
118
+
88
119
  Args:
89
120
  name: The name to clean
90
-
121
+
91
122
  Returns:
92
123
  Cleaned name
93
-
124
+
94
125
  Note:
95
126
  This is a best-effort cleaning. The result should still be validated
96
127
  with validate_name() before use.
97
128
  """
98
129
  # Convert to lowercase
99
130
  cleaned = name.lower()
100
-
131
+
101
132
  # Replace spaces with dashes
102
- cleaned = cleaned.replace(' ', '-')
103
-
133
+ cleaned = cleaned.replace(" ", "-")
134
+
104
135
  # Remove invalid characters
105
- cleaned = re.sub(r'[^a-z0-9\-_\.]', '', cleaned)
106
-
136
+ cleaned = re.sub(r"[^a-z0-9\-_\.]", "", cleaned)
137
+
107
138
  # Remove consecutive special characters
108
- cleaned = re.sub(r'[-_\.]{2,}', '-', cleaned)
109
-
139
+ cleaned = re.sub(r"[-_\.]{2,}", "-", cleaned)
140
+
110
141
  # Remove leading/trailing special characters
111
- cleaned = cleaned.strip('-_.')
112
-
142
+ cleaned = cleaned.strip("-_.")
143
+
113
144
  return cleaned
114
145
 
115
146
 
116
147
  def is_valid_name(name: str) -> bool:
117
148
  """Check if a name is valid without raising an exception.
118
-
149
+
119
150
  Args:
120
151
  name: The name to check
121
-
152
+
122
153
  Returns:
123
154
  True if valid, False otherwise
124
155
  """
@@ -126,4 +157,4 @@ def is_valid_name(name: str) -> bool:
126
157
  validate_name(name)
127
158
  return True
128
159
  except InvalidNameError:
129
- return False
160
+ return False
@@ -11,6 +11,7 @@ from enum import Enum
11
11
 
12
12
  class SQLOperation(Enum):
13
13
  """Allowed SQL operations."""
14
+
14
15
  SELECT = "SELECT"
15
16
  INSERT = "INSERT"
16
17
  UPDATE = "UPDATE"
@@ -19,37 +20,63 @@ class SQLOperation(Enum):
19
20
 
20
21
  # List of restricted DDL operations and keywords
21
22
  RESTRICTED_OPERATIONS = {
22
- 'CREATE', 'ALTER', 'DROP', 'TRUNCATE', 'RENAME',
23
- 'GRANT', 'REVOKE', 'ANALYZE', 'VACUUM', 'ATTACH',
24
- 'DETACH', 'PRAGMA', 'REINDEX', 'SAVEPOINT', 'RELEASE'
23
+ "CREATE",
24
+ "ALTER",
25
+ "DROP",
26
+ "TRUNCATE",
27
+ "RENAME",
28
+ "GRANT",
29
+ "REVOKE",
30
+ "ANALYZE",
31
+ "VACUUM",
32
+ "ATTACH",
33
+ "DETACH",
34
+ "PRAGMA",
35
+ "REINDEX",
36
+ "SAVEPOINT",
37
+ "RELEASE",
25
38
  }
26
39
 
27
40
  # Additional restricted keywords that could modify schema
28
41
  RESTRICTED_KEYWORDS = {
29
- 'ADD COLUMN', 'DROP COLUMN', 'MODIFY COLUMN',
30
- 'ADD CONSTRAINT', 'DROP CONSTRAINT', 'ADD INDEX',
31
- 'DROP INDEX', 'CREATE INDEX', 'CREATE UNIQUE',
32
- 'CREATE VIEW', 'DROP VIEW', 'CREATE TRIGGER',
33
- 'DROP TRIGGER', 'CREATE PROCEDURE', 'DROP PROCEDURE',
34
- 'CREATE FUNCTION', 'DROP FUNCTION'
42
+ "ADD COLUMN",
43
+ "DROP COLUMN",
44
+ "MODIFY COLUMN",
45
+ "ADD CONSTRAINT",
46
+ "DROP CONSTRAINT",
47
+ "ADD INDEX",
48
+ "DROP INDEX",
49
+ "CREATE INDEX",
50
+ "CREATE UNIQUE",
51
+ "CREATE VIEW",
52
+ "DROP VIEW",
53
+ "CREATE TRIGGER",
54
+ "DROP TRIGGER",
55
+ "CREATE PROCEDURE",
56
+ "DROP PROCEDURE",
57
+ "CREATE FUNCTION",
58
+ "DROP FUNCTION",
35
59
  }
36
60
 
37
61
 
38
62
  class SQLValidationError(Exception):
39
63
  """Raised when SQL query validation fails."""
64
+
40
65
  pass
41
66
 
42
67
 
43
- def validate_sql_query(query: str, allow_multiple_statements: bool = False) -> Tuple[bool, Optional[str], Optional[SQLOperation]]:
68
+ def validate_sql_query(
69
+ query: str, allow_multiple_statements: bool = False
70
+ ) -> Tuple[bool, Optional[str], Optional[SQLOperation]]:
44
71
  """Validate a SQL query to ensure it only contains allowed operations.
45
-
72
+
46
73
  Allowed operations: SELECT, INSERT, UPDATE, DELETE
47
74
  Blocked operations: All DDL operations (CREATE, ALTER, DROP, etc.)
48
-
75
+
49
76
  Args:
50
77
  query: The SQL query to validate
51
78
  allow_multiple_statements: Whether to allow multiple SQL statements (default: False)
52
-
79
+
53
80
  Returns:
54
81
  Tuple of (is_valid, error_message, operation)
55
82
  - is_valid: True if query is valid
@@ -58,80 +85,103 @@ def validate_sql_query(query: str, allow_multiple_statements: bool = False) -> T
58
85
  """
59
86
  if not query or not query.strip():
60
87
  return False, "Query cannot be empty", None
61
-
88
+
62
89
  # Normalize the query - remove comments and extra whitespace
63
90
  normalized_query = query
64
91
  # Remove single-line comments
65
- normalized_query = re.sub(r'--.*$', '', normalized_query, flags=re.MULTILINE)
92
+ normalized_query = re.sub(r"--.*$", "", normalized_query, flags=re.MULTILINE)
66
93
  # Remove multi-line comments
67
- normalized_query = re.sub(r'/\*[\s\S]*?\*/', '', normalized_query)
94
+ normalized_query = re.sub(r"/\*[\s\S]*?\*/", "", normalized_query)
68
95
  # Replace multiple spaces with single space
69
- normalized_query = re.sub(r'\s+', ' ', normalized_query)
96
+ normalized_query = re.sub(r"\s+", " ", normalized_query)
70
97
  normalized_query = normalized_query.strip().upper()
71
-
98
+
72
99
  if not normalized_query:
73
100
  return False, "Query cannot be empty after removing comments", None
74
-
101
+
75
102
  # Check for multiple statements (security risk)
76
103
  if not allow_multiple_statements:
77
104
  # Count semicolons that are not at the end
78
- semicolon_pos = normalized_query.find(';')
105
+ semicolon_pos = normalized_query.find(";")
79
106
  if semicolon_pos != -1 and semicolon_pos < len(normalized_query) - 1:
80
107
  # Check if there's non-whitespace after the semicolon
81
- remaining = normalized_query[semicolon_pos + 1:].strip()
108
+ remaining = normalized_query[semicolon_pos + 1 :].strip()
82
109
  if remaining:
83
- return False, "Multiple statements are not allowed. Please execute one query at a time.", None
84
-
110
+ return (
111
+ False,
112
+ "Multiple statements are not allowed. Please execute one query at a time.",
113
+ None,
114
+ )
115
+
85
116
  # Extract the first word (operation)
86
- first_word = normalized_query.split()[0].rstrip(';')
87
-
117
+ first_word = normalized_query.split()[0].rstrip(";")
118
+
88
119
  # Check if it's an allowed operation
89
120
  try:
90
121
  operation = SQLOperation(first_word)
91
-
122
+
92
123
  # Additional validation for UPDATE and DELETE
93
124
  if operation in (SQLOperation.UPDATE, SQLOperation.DELETE):
94
125
  # Warning if no WHERE clause (we don't block it, just log)
95
- if 'WHERE' not in normalized_query:
126
+ if "WHERE" not in normalized_query:
96
127
  import logging
97
- logging.warning(f"{operation.value} statement without WHERE clause detected")
98
-
128
+
129
+ logging.warning(
130
+ f"{operation.value} statement without WHERE clause detected"
131
+ )
132
+
99
133
  return True, None, operation
100
134
  except ValueError:
101
135
  # Not a recognized allowed operation
102
136
  pass
103
-
137
+
104
138
  # Check for restricted operations
105
139
  for restricted in RESTRICTED_OPERATIONS:
106
140
  if normalized_query.startswith(restricted):
107
- return False, f"{restricted} operations are not allowed. Only SELECT, INSERT, UPDATE, and DELETE queries are permitted.", None
108
-
141
+ return (
142
+ False,
143
+ f"{restricted} operations are not allowed. Only SELECT, INSERT, UPDATE, and DELETE queries are permitted.",
144
+ None,
145
+ )
146
+
109
147
  # Check for restricted keywords anywhere in the query
110
148
  for keyword in RESTRICTED_KEYWORDS:
111
149
  if keyword in normalized_query:
112
- return False, f"Query contains restricted operation: {keyword}. Only SELECT, INSERT, UPDATE, and DELETE queries are permitted.", None
113
-
150
+ return (
151
+ False,
152
+ f"Query contains restricted operation: {keyword}. Only SELECT, INSERT, UPDATE, and DELETE queries are permitted.",
153
+ None,
154
+ )
155
+
114
156
  # Check for WITH statements that might contain DDL
115
- if normalized_query.startswith('WITH'):
157
+ if normalized_query.startswith("WITH"):
116
158
  # Check if the CTE contains any DDL operations
117
159
  for restricted in RESTRICTED_OPERATIONS:
118
160
  if restricted in normalized_query:
119
- return False, f"CTE (WITH clause) containing {restricted} operations is not allowed.", None
120
-
161
+ return (
162
+ False,
163
+ f"CTE (WITH clause) containing {restricted} operations is not allowed.",
164
+ None,
165
+ )
166
+
121
167
  # If we get here, it's an unrecognized operation
122
- return False, "Unrecognized or restricted SQL operation. Only SELECT, INSERT, UPDATE, and DELETE queries are permitted.", None
168
+ return (
169
+ False,
170
+ "Unrecognized or restricted SQL operation. Only SELECT, INSERT, UPDATE, and DELETE queries are permitted.",
171
+ None,
172
+ )
123
173
 
124
174
 
125
175
  def validate_query_safe(query: str, allow_multiple_statements: bool = False) -> None:
126
176
  """Validate a SQL query and raise an exception if invalid.
127
-
177
+
128
178
  Args:
129
179
  query: The SQL query to validate
130
180
  allow_multiple_statements: Whether to allow multiple SQL statements
131
-
181
+
132
182
  Raises:
133
183
  SQLValidationError: If the query is invalid
134
184
  """
135
185
  is_valid, error_message, _ = validate_sql_query(query, allow_multiple_statements)
136
186
  if not is_valid:
137
- raise SQLValidationError(error_message)
187
+ raise SQLValidationError(error_message)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cinchdb
3
- Version: 0.1.3
3
+ Version: 0.1.4
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
@@ -31,7 +31,7 @@ Description-Content-Type: text/markdown
31
31
 
32
32
  NOTE: CinchDB is in early alpha. This is project to test out an idea. Do not use this in production.
33
33
 
34
- 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.
34
+ 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 that makes it easy to merge changes between branches.
35
35
 
36
36
  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.
37
37
 
@@ -0,0 +1,54 @@
1
+ cinchdb/__init__.py,sha256=NZdSzfhRguSBTjJ2dcESOQYy53OZEuBndlB7U08GMY0,179
2
+ cinchdb/__main__.py,sha256=OpkDqn9zkTZhhYgvv_grswWLAHKbmxs4M-8C6Z5HfWY,85
3
+ cinchdb/config.py,sha256=gocjMnYKLWhgvnteo6zprgwtK6Oevoxq547J_v-C9Ns,5265
4
+ cinchdb/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ cinchdb/cli/main.py,sha256=Icr_uhe_zXPAuhM9NB7evR5b1ZP7f_N40HQcC1JFhQ0,4706
6
+ cinchdb/cli/utils.py,sha256=NREFxN9k53FnPbDoPt4SXmdZzlzw9zUMv5ICQwTT8gk,5679
7
+ cinchdb/cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
8
+ cinchdb/cli/commands/branch.py,sha256=Nz8YQYJ7lizSXEAv0usTx85TDOC-N5Ul9KIxN8JQtKc,17973
9
+ cinchdb/cli/commands/codegen.py,sha256=WsRWmXNTDuaLPyECW5psXM9zOQnKHpUiv8BJnBAjMII,6189
10
+ cinchdb/cli/commands/column.py,sha256=ISHRmcoLf1fAbPqC2MaAYH7Fc6xZWtzCMSRh7_9o-lY,11757
11
+ cinchdb/cli/commands/database.py,sha256=-UCOnn3VatdNog-fX5pguJ2GKdSSXQN99-LSVwkvinY,6857
12
+ cinchdb/cli/commands/query.py,sha256=XW_YL6M5IYHHHMpVB5p-M01kawFxwDOK5B5hGIy_BA8,5044
13
+ cinchdb/cli/commands/remote.py,sha256=i07hfiAxgrROB9lVJVaKK_nWxT1SGiSbtFb4jvEwxEo,4445
14
+ cinchdb/cli/commands/table.py,sha256=NxfOTCd9beaujffiAPiW0Vko0--HS1JVeCwBMp_khx4,10518
15
+ cinchdb/cli/commands/tenant.py,sha256=cOWs9Gf13ZE4KTKJZ_AvDwFDdXBUn5i-Av4MoUsc8Go,6199
16
+ cinchdb/cli/commands/view.py,sha256=ZmS1IW7idzzHAXmgVyY3C4IQRo7toHb6fHNFY_tQJjI,6385
17
+ cinchdb/cli/handlers/__init__.py,sha256=f2f-Cc96rSBLbVsiIbf-b4pZCKZoHfmhNEvnZ0OurRs,131
18
+ cinchdb/cli/handlers/codegen_handler.py,sha256=i5we_AbiUW3zfO6pIKWxvtO8OvOqz3H__4xPmTLEuQM,6524
19
+ cinchdb/core/__init__.py,sha256=iNlT0iO9cM0HLoYwzBavUBoXRh1Tcnz1l_vfbwVxK_Q,246
20
+ cinchdb/core/connection.py,sha256=SlKyEfIpeaDws8M6SfEbvCEVnt26zBY1RYwHtTXj0kY,5110
21
+ cinchdb/core/database.py,sha256=NFAhFQuwr_NLoU_DH3rkycmGzjw9GfA-DFBJ-CyhZ8Y,17933
22
+ cinchdb/core/initializer.py,sha256=CjnJSMuR1NrHobyFfwL44tUeH8VE62q02bijEtVH3p4,6922
23
+ cinchdb/core/maintenance.py,sha256=PAgrSL7Cj9p3rKHV0h_L7gupN6nLD0-5eQpJZNiqyEs,2097
24
+ cinchdb/core/path_utils.py,sha256=J2UEu1X_NFOqDamcsrPrC7ZitGTg9Y-HFjmx4sHf5j8,3806
25
+ cinchdb/managers/__init__.py,sha256=ic61ZUdsg-muq0ETYO6fuZRQWF4j7l920PthTkt2QrE,808
26
+ cinchdb/managers/branch.py,sha256=FkF2i5vZ8ifldGm9tLcgPNymifFdBbpCrfLorIBYCiE,5330
27
+ cinchdb/managers/change_applier.py,sha256=cHPhPgbJ9jeyrb6lkfRyumS8IHat0HiWfwZh-n7ButA,14310
28
+ cinchdb/managers/change_comparator.py,sha256=08pwybpSt36cFwhZRSIkHynvFMUaLKEVwa8Ajn_R9yQ,6862
29
+ cinchdb/managers/change_tracker.py,sha256=U93BPnuGv8xSaO5qr_y5Q8ppKrVXygozdp5zUvLUqwg,5054
30
+ cinchdb/managers/codegen.py,sha256=1CfIwjgHnNDdjrq4SzQ9VE7DFgnWfk7RtpupBFUTqxk,21804
31
+ cinchdb/managers/column.py,sha256=YhYq-hnH0o2BqZkyihnsY5KIWEztzs-_iLJNZMdVUkk,20807
32
+ cinchdb/managers/data.py,sha256=4wn9fxFPhrDvtudc1pdQmr0vf0w9H92VrzAIVyTXFCY,15408
33
+ cinchdb/managers/merge_manager.py,sha256=R8S2hLkLJg4hLDpeJTzjVkduZgqPOjXtYgOSJhTXXrE,15690
34
+ cinchdb/managers/query.py,sha256=pBlbqoovnFsZ36pB7nv8NtzcTFwtT26hp8IlwjIx29Q,7301
35
+ cinchdb/managers/table.py,sha256=KWSAfZCJafKZPx-dRG7KwQUGVqVQ56ARMVBllb3VBig,13114
36
+ cinchdb/managers/tenant.py,sha256=QONC5R8tW5CJoGUxECJmQyiSP12mz3rZBmRqxCsKjmM,8726
37
+ cinchdb/managers/view.py,sha256=v9gYtRufZyxywPKLGvIjvlUXcxYh9CLRArefu9QX6zk,7809
38
+ cinchdb/models/__init__.py,sha256=382OuS0BaKPA71GjqNW5lfVhtUYqmcMlLRin7HPi6XI,602
39
+ cinchdb/models/base.py,sha256=7j4rlFTP5K9ZuF8vxwC7lMFEaL7O90NJ47Ig5i7ubcw,1320
40
+ cinchdb/models/branch.py,sha256=gRgLpRFkMC3fxf9ZigVOkS6wdkBERWqlLk0_gOYjqNk,1180
41
+ cinchdb/models/change.py,sha256=YpBWdI6yMT3uucd8duET9s75xr5JUWJqurkkyTlXPlk,1449
42
+ cinchdb/models/database.py,sha256=QrWd_SkE1G8TMWflO4sXRUbSdbqcrfGOt2e-PS7OW7A,971
43
+ cinchdb/models/project.py,sha256=6GMXUZUsEIebqQJgRXIthWzpWKuNNmJ3drgI1vFDrMo,644
44
+ cinchdb/models/table.py,sha256=k2_nnyW1E6-UM2Zw49K5njP_fxySW3HVWymcR_a0e_0,2759
45
+ cinchdb/models/tenant.py,sha256=UKYTKM4mQH3IqEjI_tOU5CszwBWH4cXa3lI0mpMFF_4,967
46
+ cinchdb/models/view.py,sha256=q6j-jYzFJuhRJO87rKt6Uv8hOizHQx8xwoPKoH6XnNY,530
47
+ cinchdb/utils/__init__.py,sha256=yQQhEjndDiB2SUJybUmp9dvEOQKiR-GySe-WiCius5E,490
48
+ cinchdb/utils/name_validator.py,sha256=dyGX5bjlTFRA9EGrWRQKp6kR__HSV04hLV5VueJs4IQ,4027
49
+ cinchdb/utils/sql_validator.py,sha256=aWOGlPX0gBkuR6R1EBP2stbP4PHZuI6FUBi2Ljx7JUI,5815
50
+ cinchdb-0.1.4.dist-info/METADATA,sha256=VAr-tVrdoG7BT0GSZqMZdjEi4H7sYwg0CK2PE7kFAFU,5855
51
+ cinchdb-0.1.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
52
+ cinchdb-0.1.4.dist-info/entry_points.txt,sha256=VBOIzvnGbkKudMCCmNORS3885QSyjZUVKJQ-Syqa62w,47
53
+ cinchdb-0.1.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
54
+ cinchdb-0.1.4.dist-info/RECORD,,
@@ -1,53 +0,0 @@
1
- cinchdb/__init__.py,sha256=NZdSzfhRguSBTjJ2dcESOQYy53OZEuBndlB7U08GMY0,179
2
- cinchdb/__main__.py,sha256=OpkDqn9zkTZhhYgvv_grswWLAHKbmxs4M-8C6Z5HfWY,85
3
- cinchdb/config.py,sha256=Exzf0hCJgcg0PRRQz8EG7XFipx6fIVKO7IsQhpc0Q4o,6187
4
- cinchdb/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- cinchdb/cli/main.py,sha256=_vBSigtAcYgGBB4qRt2p3ZH8QZ4Osk5rLRe5cOD5ryU,4335
6
- cinchdb/cli/utils.py,sha256=Alh3plAiVOGSk_ETqTmh2rYHHFULelizsQOR4e-_KJw,5661
7
- cinchdb/cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
8
- cinchdb/cli/commands/branch.py,sha256=pNltZ2yyUuVGG1D_x5Rmr3lcyr0ibC98xEQevTtt0Q0,17890
9
- cinchdb/cli/commands/codegen.py,sha256=WsRWmXNTDuaLPyECW5psXM9zOQnKHpUiv8BJnBAjMII,6189
10
- cinchdb/cli/commands/column.py,sha256=CQJZ-mkv_qaBnZDrNhKaunUdxVyz5zmbsZakUnz5-dg,11634
11
- cinchdb/cli/commands/database.py,sha256=TxJ3xZfAb7zyq2NrnL1PPYQWENsjMYq_GjuS3J0yuyw,6865
12
- cinchdb/cli/commands/query.py,sha256=yce0rvp3WQCzFA08cP1DoP2Yir4NSYxX1XxXPmmo3lM,5120
13
- cinchdb/cli/commands/remote.py,sha256=LecazBIlEAx8J85vONDrQyy3OEYkmYGCeTGS-c0PD1Y,4500
14
- cinchdb/cli/commands/table.py,sha256=ApDcn-iJ-Cjsf4ubQh8UVNBxJmhLQ_O2FxQeBRk6xMI,10511
15
- cinchdb/cli/commands/tenant.py,sha256=G9jxj8rrSfXJqYYi6Lls21wDShYr1aDgj_vffbjG-j4,6223
16
- cinchdb/cli/commands/view.py,sha256=ZmS1IW7idzzHAXmgVyY3C4IQRo7toHb6fHNFY_tQJjI,6385
17
- cinchdb/cli/handlers/__init__.py,sha256=f2f-Cc96rSBLbVsiIbf-b4pZCKZoHfmhNEvnZ0OurRs,131
18
- cinchdb/cli/handlers/codegen_handler.py,sha256=i5we_AbiUW3zfO6pIKWxvtO8OvOqz3H__4xPmTLEuQM,6524
19
- cinchdb/core/__init__.py,sha256=7yh27tcLZAtTDGxz6wLtd-fnKZTXXlQE_3ZAY8FT8OU,148
20
- cinchdb/core/connection.py,sha256=SlKyEfIpeaDws8M6SfEbvCEVnt26zBY1RYwHtTXj0kY,5110
21
- cinchdb/core/database.py,sha256=QDz3imoCvrWAA4zLuYaM6lUNRKDQWrYAQPfIJyZkgyw,17984
22
- cinchdb/core/maintenance.py,sha256=PAgrSL7Cj9p3rKHV0h_L7gupN6nLD0-5eQpJZNiqyEs,2097
23
- cinchdb/core/path_utils.py,sha256=J2UEu1X_NFOqDamcsrPrC7ZitGTg9Y-HFjmx4sHf5j8,3806
24
- cinchdb/managers/__init__.py,sha256=ic61ZUdsg-muq0ETYO6fuZRQWF4j7l920PthTkt2QrE,808
25
- cinchdb/managers/branch.py,sha256=uj_ReZF9lmXgwn0DhAh6xCrE2LieG1CVHHEeOzhnr1E,5373
26
- cinchdb/managers/change_applier.py,sha256=cHPhPgbJ9jeyrb6lkfRyumS8IHat0HiWfwZh-n7ButA,14310
27
- cinchdb/managers/change_comparator.py,sha256=08pwybpSt36cFwhZRSIkHynvFMUaLKEVwa8Ajn_R9yQ,6862
28
- cinchdb/managers/change_tracker.py,sha256=U93BPnuGv8xSaO5qr_y5Q8ppKrVXygozdp5zUvLUqwg,5054
29
- cinchdb/managers/codegen.py,sha256=1CfIwjgHnNDdjrq4SzQ9VE7DFgnWfk7RtpupBFUTqxk,21804
30
- cinchdb/managers/column.py,sha256=OvBm2irGhvIJEb2e5vSdBPQn5JUb0y9r89IsiMgQeeo,20858
31
- cinchdb/managers/data.py,sha256=4wn9fxFPhrDvtudc1pdQmr0vf0w9H92VrzAIVyTXFCY,15408
32
- cinchdb/managers/merge_manager.py,sha256=R8S2hLkLJg4hLDpeJTzjVkduZgqPOjXtYgOSJhTXXrE,15690
33
- cinchdb/managers/query.py,sha256=c91J5FAR-Ze5Zy5HNEVIPvc8yuxe-xIv6XHH-lmdB2k,7307
34
- cinchdb/managers/table.py,sha256=9Z_RJxZ9fMm_gYbmHXGG0-xZ0cNia1y5tusnydW66_U,13155
35
- cinchdb/managers/tenant.py,sha256=ZMx9H8XHua512fFRK2xBxa3xjqJJ551xp399mGm16s4,8750
36
- cinchdb/managers/view.py,sha256=v9gYtRufZyxywPKLGvIjvlUXcxYh9CLRArefu9QX6zk,7809
37
- cinchdb/models/__init__.py,sha256=382OuS0BaKPA71GjqNW5lfVhtUYqmcMlLRin7HPi6XI,602
38
- cinchdb/models/base.py,sha256=7j4rlFTP5K9ZuF8vxwC7lMFEaL7O90NJ47Ig5i7ubcw,1320
39
- cinchdb/models/branch.py,sha256=vKw7rtwxKSpgXAHBKwf5Fkd4LjtiZcfDwtAqeq1LoBE,1180
40
- cinchdb/models/change.py,sha256=YpBWdI6yMT3uucd8duET9s75xr5JUWJqurkkyTlXPlk,1449
41
- cinchdb/models/database.py,sha256=Z_XZwBfjcZe7x6IsFD5fgD3a-k5ESzRoVukMlPpTIek,971
42
- cinchdb/models/project.py,sha256=6GMXUZUsEIebqQJgRXIthWzpWKuNNmJ3drgI1vFDrMo,644
43
- cinchdb/models/table.py,sha256=s6BGoHDuA-yzqQL9papRTVT2WcHjuY-SnoanGFDlFIE,2793
44
- cinchdb/models/tenant.py,sha256=Jut8qoHX79OG3zDNXAdDqzGmlGiV8trGe3t5kXbFt1E,967
45
- cinchdb/models/view.py,sha256=q6j-jYzFJuhRJO87rKt6Uv8hOizHQx8xwoPKoH6XnNY,530
46
- cinchdb/utils/__init__.py,sha256=1mBU1H2C9urYA8Z_v5BTdAfDe0mQ6GMAK0AM3zRPv5k,487
47
- cinchdb/utils/name_validator.py,sha256=GgzN7Z5XoEIt595n4_6TWwZQZegVNRIB4evzg3r67Rg,4010
48
- cinchdb/utils/sql_validator.py,sha256=7STxsVO7bD4gZ8mfimQSt4_Yfckw62plUS_X_xJ48Vo,5427
49
- cinchdb-0.1.3.dist-info/METADATA,sha256=QYfexlMLVbnspKmQKADSVU3XKLMtUpITicgS5o1fWBE,5802
50
- cinchdb-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
51
- cinchdb-0.1.3.dist-info/entry_points.txt,sha256=VBOIzvnGbkKudMCCmNORS3885QSyjZUVKJQ-Syqa62w,47
52
- cinchdb-0.1.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
53
- cinchdb-0.1.3.dist-info/RECORD,,