dzql 0.3.1 → 0.3.2

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.
@@ -46,17 +46,11 @@ SELECT dzql.register_entity(
46
46
  array['title', 'description'], -- Searchable fields
47
47
  '{}'::jsonb, -- FK includes
48
48
  false, -- Soft delete
49
- '{}'::jsonb, -- Graph rules
50
- jsonb_build_object( -- Notification paths
51
- 'owner', array['@user_id']
52
- ),
53
- jsonb_build_object( -- Permission paths
54
- 'view', array['@user_id'],
55
- 'create', array['@user_id'],
56
- 'update', array['@user_id'],
57
- 'delete', array['@user_id']
58
- ),
59
- '{}'::jsonb -- Temporal config
49
+ '{}'::jsonb, -- Temporal config
50
+ '{}'::jsonb, -- Notification paths
51
+ '{}'::jsonb, -- Permission paths
52
+ '{}'::jsonb, -- Graph rules (including M2M)
53
+ '{}'::jsonb -- Field defaults
60
54
  );
61
55
  ```
62
56
 
@@ -67,6 +61,51 @@ This generates 5 PostgreSQL functions:
67
61
  - `lookup_todos(params, user_id)` - Autocomplete
68
62
  - `search_todos(params, user_id)` - Search with filters
69
63
 
64
+ ## Compiler Features (v0.3.1+)
65
+
66
+ The compiler generates **static, optimized SQL** with zero runtime interpretation:
67
+
68
+ ### Many-to-Many Relationships
69
+ ```sql
70
+ SELECT dzql.register_entity(
71
+ 'brands', 'name', ARRAY['name'],
72
+ '{}', false, '{}', '{}', '{}',
73
+ '{
74
+ "many_to_many": {
75
+ "tags": {
76
+ "junction_table": "brand_tags",
77
+ "local_key": "brand_id",
78
+ "foreign_key": "tag_id",
79
+ "target_entity": "tags",
80
+ "id_field": "tag_ids",
81
+ "expand": false
82
+ }
83
+ }
84
+ }',
85
+ '{}'
86
+ );
87
+ ```
88
+
89
+ **Generated code:** Static M2M sync blocks (50-100x faster than generic operations)
90
+ - No runtime loops
91
+ - All table/column names are literals
92
+ - PostgreSQL can fully optimize and cache plans
93
+
94
+ See [Many-to-Many Guide](../guides/many-to-many.md) for details.
95
+
96
+ ### Field Defaults
97
+ ```sql
98
+ '{
99
+ "owner_id": "@user_id",
100
+ "created_at": "@now",
101
+ "status": "draft"
102
+ }'
103
+ ```
104
+
105
+ **Generated code:** Auto-populates fields on INSERT
106
+
107
+ See [Field Defaults Guide](../guides/field-defaults.md) for details.
108
+
70
109
  ## Architecture
71
110
 
72
111
  The compiler uses a three-phase approach:
@@ -4,7 +4,7 @@ First-class support for many-to-many relationships with automatic junction table
4
4
 
5
5
  ## Overview
6
6
 
7
- DZQL now provides built-in support for many-to-many (M2M) relationships through junction tables. Define the relationship once in your entity configuration, and DZQL handles:
7
+ DZQL provides built-in support for many-to-many (M2M) relationships through junction tables. Define the relationship once in your entity configuration, and DZQL handles:
8
8
 
9
9
  - Junction table synchronization
10
10
  - Atomic updates in single API calls
@@ -19,6 +19,24 @@ DZQL now provides built-in support for many-to-many (M2M) relationships through
19
19
  - **Less Boilerplate** - No custom toggle functions needed
20
20
  - **Performance Control** - Optional expansion (off by default)
21
21
 
22
+ ## Generic vs Compiled Operations
23
+
24
+ M2M support works in **both** modes:
25
+
26
+ ### Generic Operations (Runtime)
27
+ - Uses `dzql.generic_save()` and dynamic SQL
28
+ - Interprets M2M config at runtime (~5-10ms overhead per relationship)
29
+ - Works immediately after `register_entity()` call
30
+ - Good for development and entities with simple M2M
31
+
32
+ ### Compiled Operations (v0.3.1+) - RECOMMENDED
33
+ - Generates **static SQL** at compile time
34
+ - **50-100x faster** - zero interpretation overhead
35
+ - All table/column names are literals (PostgreSQL optimizes fully)
36
+ - Recommended for production and complex M2M scenarios
37
+
38
+ See [Compiler Guide](../compiler/README.md) for compilation workflow.
39
+
22
40
  ## Quick Example
23
41
 
24
42
  ### Setup
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dzql",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "PostgreSQL-powered framework with zero boilerplate CRUD operations and real-time WebSocket synchronization",
5
5
  "type": "module",
6
6
  "main": "src/server/index.js",
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "scripts": {
24
24
  "test": "bun test",
25
- "prepublishOnly": "echo '✅ Publishing DZQL v0.3.1...'"
25
+ "prepublishOnly": "echo '✅ Publishing DZQL v0.3.2...'"
26
26
  },
27
27
  "dependencies": {
28
28
  "jose": "^6.1.0",
@@ -176,6 +176,9 @@ export class EntityParser {
176
176
  _parseJSON(str) {
177
177
  if (!str || str === '{}' || str === "'{}'") return {};
178
178
 
179
+ // Strip SQL comments before parsing
180
+ str = str.replace(/--[^\n]*/g, '').trim();
181
+
179
182
  // Handle jsonb_build_object(...) calls
180
183
  if (str.includes('jsonb_build_object')) {
181
184
  return this._parseJSONBuildObject(str);
@@ -184,9 +187,11 @@ export class EntityParser {
184
187
  // Handle JSON string literals
185
188
  if (str.startsWith("'") && str.endsWith("'")) {
186
189
  try {
187
- return JSON.parse(str.slice(1, -1).replace(/''/g, "'"));
190
+ // Remove outer quotes and unescape SQL quotes
191
+ const jsonStr = str.slice(1, -1).replace(/''/g, "'");
192
+ return JSON.parse(jsonStr);
188
193
  } catch (e) {
189
- console.warn('Failed to parse JSON:', str, e);
194
+ console.warn('Failed to parse JSON:', str.substring(0, 100) + '...', e);
190
195
  return {};
191
196
  }
192
197
  }