cinchdb 0.1.5__tar.gz → 0.1.6__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 (54) hide show
  1. {cinchdb-0.1.5 → cinchdb-0.1.6}/PKG-INFO +24 -6
  2. {cinchdb-0.1.5 → cinchdb-0.1.6}/README.md +23 -5
  3. {cinchdb-0.1.5 → cinchdb-0.1.6}/pyproject.toml +1 -1
  4. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/core/database.py +45 -14
  5. {cinchdb-0.1.5 → cinchdb-0.1.6}/.gitignore +0 -0
  6. {cinchdb-0.1.5 → cinchdb-0.1.6}/LICENSE +0 -0
  7. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/__init__.py +0 -0
  8. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/__main__.py +0 -0
  9. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/__init__.py +0 -0
  10. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/__init__.py +0 -0
  11. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/branch.py +0 -0
  12. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/codegen.py +0 -0
  13. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/column.py +0 -0
  14. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/database.py +0 -0
  15. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/query.py +0 -0
  16. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/remote.py +0 -0
  17. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/table.py +0 -0
  18. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/tenant.py +0 -0
  19. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/commands/view.py +0 -0
  20. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/handlers/__init__.py +0 -0
  21. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/handlers/codegen_handler.py +0 -0
  22. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/main.py +0 -0
  23. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/cli/utils.py +0 -0
  24. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/config.py +0 -0
  25. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/core/__init__.py +0 -0
  26. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/core/connection.py +0 -0
  27. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/core/initializer.py +0 -0
  28. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/core/maintenance.py +0 -0
  29. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/core/path_utils.py +0 -0
  30. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/__init__.py +0 -0
  31. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/branch.py +0 -0
  32. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/change_applier.py +0 -0
  33. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/change_comparator.py +0 -0
  34. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/change_tracker.py +0 -0
  35. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/codegen.py +0 -0
  36. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/column.py +0 -0
  37. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/data.py +0 -0
  38. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/merge_manager.py +0 -0
  39. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/query.py +0 -0
  40. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/table.py +0 -0
  41. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/tenant.py +0 -0
  42. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/managers/view.py +0 -0
  43. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/__init__.py +0 -0
  44. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/base.py +0 -0
  45. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/branch.py +0 -0
  46. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/change.py +0 -0
  47. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/database.py +0 -0
  48. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/project.py +0 -0
  49. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/table.py +0 -0
  50. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/tenant.py +0 -0
  51. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/models/view.py +0 -0
  52. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/utils/__init__.py +0 -0
  53. {cinchdb-0.1.5 → cinchdb-0.1.6}/src/cinchdb/utils/name_validator.py +0 -0
  54. {cinchdb-0.1.5 → cinchdb-0.1.6}/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.5
3
+ Version: 0.1.6
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,9 +31,9 @@ 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 that makes it easy to merge changes between branches.
34
+ CinchDB is for projects that need fast queries, 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
- 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.
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
 
38
38
  Because it's so lightweight and its only dependencies are pydantic, requests, and Typer, it makes for a perfect local development database that can be controlled programmatically.
39
39
 
@@ -58,6 +58,7 @@ cinch branch merge-into-main feature
58
58
  cinch tenant create customer_a
59
59
  cinch query "SELECT * FROM users" --tenant customer_a
60
60
 
61
+ # Coming soon
61
62
  # Connect to remote CinchDB instance
62
63
  cinch remote add production https://your-cinchdb-server.com your-api-key
63
64
  cinch remote use production
@@ -76,7 +77,7 @@ CinchDB combines SQLite with Git-like workflows for database schema management:
76
77
  - **Safe structure changes** - change merges happen atomically with zero rollback risk (seriously)
77
78
  - **Remote connectivity** - Connect to hosted CinchDB instances
78
79
  - **Type-safe SDK** - Python and TypeScript SDKs with full type safety
79
- - **Remote-capable** - CLI and SDK can connect to remote instances
80
+ - **Remote-capable** - coming soon - CLI and SDK can connect to remote instances
80
81
  - **SDK generation from database schema** - Generate a typesafe SDK from your database models for CRUD operations
81
82
 
82
83
  ## Installation
@@ -128,13 +129,30 @@ db.create_table("posts", [
128
129
  # Query data
129
130
  results = db.query("SELECT * FROM posts WHERE title LIKE ?", ["%python%"])
130
131
 
131
- # CRUD operations
132
+ # CRUD operations - single insert
132
133
  post_id = db.insert("posts", {"title": "Hello World", "content": "First post"})
134
+
135
+ # Batch insert - multiple records at once
136
+ posts = db.insert("posts",
137
+ {"title": "First", "content": "Content 1"},
138
+ {"title": "Second", "content": "Content 2"},
139
+ {"title": "Third", "content": "Content 3"}
140
+ )
141
+
142
+ # Or with a list using star expansion
143
+ post_list = [
144
+ {"title": "Post A", "content": "Content A"},
145
+ {"title": "Post B", "content": "Content B"}
146
+ ]
147
+ results = db.insert("posts", *post_list)
148
+
133
149
  db.update("posts", post_id, {"content": "Updated content"})
134
150
  ```
135
151
 
136
152
  ### Remote Connection
137
153
 
154
+ Coming soon.
155
+
138
156
  ```python
139
157
  # Connect to remote instance
140
158
  db = cinchdb.connect("myapp", url="https://your-cinchdb-server.com", api_key="your-api-key")
@@ -144,7 +162,7 @@ results = db.query("SELECT * FROM users")
144
162
  user_id = db.insert("users", {"username": "alice", "email": "alice@example.com"})
145
163
  ```
146
164
 
147
- ## Remote Access
165
+ ## Remote Access - coming soon
148
166
 
149
167
  Connect to a remote CinchDB instance:
150
168
 
@@ -4,9 +4,9 @@
4
4
 
5
5
  NOTE: CinchDB is in early alpha. This is project to test out an idea. Do not use this in production.
6
6
 
7
- 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.
7
+ CinchDB is for projects that need fast queries, 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.
8
8
 
9
- 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.
9
+ 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.
10
10
 
11
11
  Because it's so lightweight and its only dependencies are pydantic, requests, and Typer, it makes for a perfect local development database that can be controlled programmatically.
12
12
 
@@ -31,6 +31,7 @@ cinch branch merge-into-main feature
31
31
  cinch tenant create customer_a
32
32
  cinch query "SELECT * FROM users" --tenant customer_a
33
33
 
34
+ # Coming soon
34
35
  # Connect to remote CinchDB instance
35
36
  cinch remote add production https://your-cinchdb-server.com your-api-key
36
37
  cinch remote use production
@@ -49,7 +50,7 @@ CinchDB combines SQLite with Git-like workflows for database schema management:
49
50
  - **Safe structure changes** - change merges happen atomically with zero rollback risk (seriously)
50
51
  - **Remote connectivity** - Connect to hosted CinchDB instances
51
52
  - **Type-safe SDK** - Python and TypeScript SDKs with full type safety
52
- - **Remote-capable** - CLI and SDK can connect to remote instances
53
+ - **Remote-capable** - coming soon - CLI and SDK can connect to remote instances
53
54
  - **SDK generation from database schema** - Generate a typesafe SDK from your database models for CRUD operations
54
55
 
55
56
  ## Installation
@@ -101,13 +102,30 @@ db.create_table("posts", [
101
102
  # Query data
102
103
  results = db.query("SELECT * FROM posts WHERE title LIKE ?", ["%python%"])
103
104
 
104
- # CRUD operations
105
+ # CRUD operations - single insert
105
106
  post_id = db.insert("posts", {"title": "Hello World", "content": "First post"})
107
+
108
+ # Batch insert - multiple records at once
109
+ posts = db.insert("posts",
110
+ {"title": "First", "content": "Content 1"},
111
+ {"title": "Second", "content": "Content 2"},
112
+ {"title": "Third", "content": "Content 3"}
113
+ )
114
+
115
+ # Or with a list using star expansion
116
+ post_list = [
117
+ {"title": "Post A", "content": "Content A"},
118
+ {"title": "Post B", "content": "Content B"}
119
+ ]
120
+ results = db.insert("posts", *post_list)
121
+
106
122
  db.update("posts", post_id, {"content": "Updated content"})
107
123
  ```
108
124
 
109
125
  ### Remote Connection
110
126
 
127
+ Coming soon.
128
+
111
129
  ```python
112
130
  # Connect to remote instance
113
131
  db = cinchdb.connect("myapp", url="https://your-cinchdb-server.com", api_key="your-api-key")
@@ -117,7 +135,7 @@ results = db.query("SELECT * FROM users")
117
135
  user_id = db.insert("users", {"username": "alice", "email": "alice@example.com"})
118
136
  ```
119
137
 
120
- ## Remote Access
138
+ ## Remote Access - coming soon
121
139
 
122
140
  Connect to a remote CinchDB instance:
123
141
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cinchdb"
3
- version = "0.1.5"
3
+ version = "0.1.6"
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"
@@ -363,23 +363,37 @@ class CinchDB:
363
363
  "POST", "/tables", json={"name": name, "columns": columns_data}
364
364
  )
365
365
 
366
- def insert(self, table: str, data: Dict[str, Any]) -> Dict[str, Any]:
367
- """Insert a record into a table.
366
+ def insert(self, table: str, *data: Dict[str, Any]) -> Dict[str, Any] | List[Dict[str, Any]]:
367
+ """Insert one or more records into a table.
368
368
 
369
369
  Args:
370
370
  table: Table name
371
- data: Record data as dictionary
371
+ *data: One or more record data dictionaries
372
372
 
373
373
  Returns:
374
- Inserted record with generated fields (id, created_at, updated_at)
374
+ Single record dict if one record inserted, list of dicts if multiple
375
375
 
376
376
  Examples:
377
- # Simple insert
377
+ # Single insert
378
378
  db.insert("users", {"name": "John", "email": "john@example.com"})
379
379
 
380
- # Insert with custom ID
381
- db.insert("products", {"id": "prod-123", "name": "Widget", "price": 9.99})
380
+ # Multiple inserts using star expansion
381
+ db.insert("users",
382
+ {"name": "John", "email": "john@example.com"},
383
+ {"name": "Jane", "email": "jane@example.com"},
384
+ {"name": "Bob", "email": "bob@example.com"}
385
+ )
386
+
387
+ # Or with a list using star expansion
388
+ users = [
389
+ {"name": "Alice", "email": "alice@example.com"},
390
+ {"name": "Charlie", "email": "charlie@example.com"}
391
+ ]
392
+ db.insert("users", *users)
382
393
  """
394
+ if not data:
395
+ raise ValueError("At least one record must be provided")
396
+
383
397
  if self.is_local:
384
398
  # Initialize data manager if needed
385
399
  if self._data_manager is None:
@@ -387,14 +401,31 @@ class CinchDB:
387
401
  self._data_manager = DataManager(
388
402
  self.project_dir, self.database, self.branch, self.tenant
389
403
  )
390
- # Use the new create_from_dict method
391
- return self._data_manager.create_from_dict(table, data)
404
+
405
+ # Single record
406
+ if len(data) == 1:
407
+ return self._data_manager.create_from_dict(table, data[0])
408
+
409
+ # Multiple records - batch insert
410
+ results = []
411
+ for record in data:
412
+ result = self._data_manager.create_from_dict(table, record)
413
+ results.append(result)
414
+ return results
392
415
  else:
393
- # Remote insert - use new data CRUD endpoint
394
- result = self._make_request(
395
- "POST", f"/tables/{table}/data", json={"data": data}
396
- )
397
- return result
416
+ # Remote insert
417
+ if len(data) == 1:
418
+ # Single record - use existing endpoint
419
+ result = self._make_request(
420
+ "POST", f"/tables/{table}/data", json={"data": data[0]}
421
+ )
422
+ return result
423
+ else:
424
+ # Multiple records - use bulk endpoint
425
+ result = self._make_request(
426
+ "POST", f"/tables/{table}/data/bulk", json={"records": list(data)}
427
+ )
428
+ return result
398
429
 
399
430
  def update(self, table: str, id: str, data: Dict[str, Any]) -> Dict[str, Any]:
400
431
  """Update a record in a table.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes