cinchdb 0.1.2__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/cli/commands/branch.py +22 -13
- cinchdb/cli/commands/column.py +27 -14
- cinchdb/cli/commands/database.py +2 -2
- cinchdb/cli/commands/query.py +19 -12
- cinchdb/cli/commands/remote.py +32 -28
- cinchdb/cli/commands/table.py +20 -16
- cinchdb/cli/commands/tenant.py +4 -4
- cinchdb/cli/main.py +21 -11
- cinchdb/cli/utils.py +8 -6
- cinchdb/config.py +18 -45
- cinchdb/core/__init__.py +2 -1
- cinchdb/core/database.py +9 -5
- cinchdb/core/initializer.py +214 -0
- cinchdb/managers/branch.py +1 -3
- cinchdb/managers/column.py +13 -9
- cinchdb/managers/query.py +12 -6
- cinchdb/managers/table.py +12 -9
- cinchdb/managers/tenant.py +3 -3
- cinchdb/models/branch.py +1 -1
- cinchdb/models/database.py +1 -1
- cinchdb/models/table.py +5 -8
- cinchdb/models/tenant.py +1 -1
- cinchdb/utils/__init__.py +5 -5
- cinchdb/utils/name_validator.py +62 -31
- cinchdb/utils/sql_validator.py +91 -41
- {cinchdb-0.1.2.dist-info → cinchdb-0.1.4.dist-info}/METADATA +2 -2
- cinchdb-0.1.4.dist-info/RECORD +54 -0
- cinchdb-0.1.2.dist-info/RECORD +0 -53
- {cinchdb-0.1.2.dist-info → cinchdb-0.1.4.dist-info}/WHEEL +0 -0
- {cinchdb-0.1.2.dist-info → cinchdb-0.1.4.dist-info}/entry_points.txt +0 -0
- {cinchdb-0.1.2.dist-info → cinchdb-0.1.4.dist-info}/licenses/LICENSE +0 -0
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(
|
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
|
+
]
|
cinchdb/utils/name_validator.py
CHANGED
@@ -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
|
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 = {
|
16
|
-
|
17
|
-
|
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
|
-
- Contain only lowercase letters (a-z), numbers (0-9), dash (-), underscore (_)
|
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
|
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
|
106
|
-
|
136
|
+
cleaned = re.sub(r"[^a-z0-9\-_\.]", "", cleaned)
|
137
|
+
|
107
138
|
# Remove consecutive special characters
|
108
|
-
cleaned = re.sub(r
|
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
|
cinchdb/utils/sql_validator.py
CHANGED
@@ -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
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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(
|
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
|
92
|
+
normalized_query = re.sub(r"--.*$", "", normalized_query, flags=re.MULTILINE)
|
66
93
|
# Remove multi-line comments
|
67
|
-
normalized_query = re.sub(r
|
94
|
+
normalized_query = re.sub(r"/\*[\s\S]*?\*/", "", normalized_query)
|
68
95
|
# Replace multiple spaces with single space
|
69
|
-
normalized_query = re.sub(r
|
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
|
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
|
126
|
+
if "WHERE" not in normalized_query:
|
96
127
|
import logging
|
97
|
-
|
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
|
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
|
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(
|
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
|
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
|
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
|
+
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,,
|
cinchdb-0.1.2.dist-info/RECORD
DELETED
@@ -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=sOeufsnIH2b7I9C3xUkQdmNv8NgnReVb6BVJkczwbeE,3955
|
48
|
-
cinchdb/utils/sql_validator.py,sha256=7STxsVO7bD4gZ8mfimQSt4_Yfckw62plUS_X_xJ48Vo,5427
|
49
|
-
cinchdb-0.1.2.dist-info/METADATA,sha256=JpVRmU-ESHcuOVkon7bhSDSxy08wnEunEkKivHSVG24,5802
|
50
|
-
cinchdb-0.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
51
|
-
cinchdb-0.1.2.dist-info/entry_points.txt,sha256=VBOIzvnGbkKudMCCmNORS3885QSyjZUVKJQ-Syqa62w,47
|
52
|
-
cinchdb-0.1.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
53
|
-
cinchdb-0.1.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|