Skip to content

Commit 171ae14

Browse files
authored
Merge pull request #123 from sqlitecloud/marcobambini-patch-1
Update pub-sub.mdx
2 parents 8c26777 + a1940f3 commit 171ae14

File tree

1 file changed

+182
-86
lines changed

1 file changed

+182
-86
lines changed

sqlite-cloud/platform/pub-sub.mdx

Lines changed: 182 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -6,141 +6,237 @@ status: publish
66
slug: pub-sub
77
---
88

9-
Pub/Sub is a messaging pattern that allows multiple applications to communicate with each other asynchronously. In the context of **SQLiteCloud**, Pub/Sub can be used to provide real-time updates and notifications to subscribed applications whenever data changes in the database or it can be used to send payloads (messages) to anyone subscribed to a channel. Here's how it works:
9+
# SQLiteCloud Pub/Sub System
1010

11-
**Publishers:** Publishers are responsible for sending messages or notifications to the system whenever a change occurs in the database. Publishers can be any application that has write access to the database, including web servers, mobile apps, or background processes. A Publisher can also be anyone who NOTIFY a payload to a specific channel (without any write database operation).
11+
**Publish/Subscribe (Pub/Sub)** is a messaging pattern that enables asynchronous communication between multiple applications. In the context of **SQLiteCloud**, Pub/Sub provides a robust way to deliver real-time updates or custom messages to subscribed clients when data changes or explicit notifications are issued.
1212

13-
**Subscribers:** Subscribers are applications that want to receive updates whenever a change occurs in the database or whenever someone send a message to a specific channel.
13+
This feature is particularly useful for building reactive applications, synchronizing distributed systems, and enabling event-driven architectures around your SQLite databases.
1414

15-
**Channels:** Channels are messaging patterns through which messages are sent and received. Publishers send messages to specific channel, and subscribers can subscribe to one or more channel to receive notifications. A channel can be a database table or a unique name not bound to any database entity.
15+
---
16+
17+
## Core Concepts
18+
19+
### **Publishers**
20+
21+
Publishers are entities that send messages or notifications. In **SQLiteCloud**, a publisher can:
22+
23+
* Modify a database (triggering automatic Pub/Sub events on commit).
24+
* Explicitly send a message using the `NOTIFY` command, even without making changes to the database.
25+
26+
Any client with write access—such as a web server, mobile app, or background process—can act as a publisher.
27+
28+
### **Subscribers**
29+
30+
Subscribers are clients that listen for messages or data change events. They can subscribe to:
31+
32+
* A **channel** representing a database table (to receive change events).
33+
* A **named message channel** (for general-purpose messages).
34+
35+
Subscribers will receive all messages published on the channels they subscribe to.
36+
37+
### **Channels**
38+
39+
Channels are the communication endpoints used for Pub/Sub messaging. A channel can be:
40+
41+
* A **database table name**, used to deliver change notifications.
42+
* A **custom channel name**, used to send arbitrary messages.
1643

17-
Here are some of the capabilities that Pub/Sub provides for a database management system:
44+
Channels are **not bound** to any database entity unless explicitly tied to a table.
1845

19-
* Real-time updates: With Pub/Sub, subscribers can receive real-time updates whenever data changes in the database. This can be useful for applications that need to display real-time information to users, such as stock tickers or social media feeds.
46+
---
47+
48+
## Benefits of Pub/Sub in SQLiteCloud
2049

21-
* Scalability: Pub/Sub provides a scalable solution for database notifications, allowing multiple subscribers to receive updates without impacting database performance.
50+
* **Real-time Updates**
51+
Instantly notify subscribers when data changes. Useful for dashboards, live feeds, or collaborative apps.
2252

23-
* Customizable filtering: Pub/Sub allows subscribers to customize the types of messages they receive by filtering on specific topics or keywords. This can help reduce network traffic and improve application performance.
53+
* **Scalability**
54+
One publisher can broadcast to many subscribers with minimal overhead on the database.
2455

25-
* Fault tolerance: Pub/Sub systems are designed to be fault-tolerant, ensuring that messages are not lost even if a subscriber or publisher goes offline.
56+
* **Message Filtering**
57+
Subscribers can choose specific channels, reducing unnecessary data traffic.
2658

27-
Overall, Pub/Sub provides a powerful messaging system for database management systems, enabling real-time updates and notifications for subscribed applications while maintaining scalability, reliability, and performance.
59+
* **Fault Tolerance**
60+
Notifications are delivered reliably. If a subscriber or publisher disconnects, the system continues to function without losing messages.
61+
62+
---
2863

29-
## Pub/Sub Payload Format
64+
## Payload Format
3065

31-
JSON is used to deliver payload to all listening clients. JSON format depends on the operation type. In case of database tables, notifications occur on COMMIT so the same JSON can collect more changes related to that table. **SQLite Cloud** guarantees **one JSON per channel**.
66+
All Pub/Sub messages in **SQLiteCloud** are delivered as **JSON** objects. The structure of the payload depends on the type of event:
67+
68+
### 1. **NOTIFY Message Payload**
69+
70+
Sent explicitly by clients using the `NOTIFY` command.
3271

33-
**1. NOTIFY payload**
3472
```json
3573
{
36-
sender: "UUID",
37-
channel: "name",
38-
type: "MESSAGE",
39-
payload: "Message content here" // payload is optional
74+
"sender": "UUID",
75+
"channel": "name",
76+
"channel_type": "MESSAGE",
77+
"payload": "Message content here"
4078
}
4179
```
4280

81+
* **sender**: UUID of the client that sent the message.
82+
* **channel**: Target channel name.
83+
* **channel\_type**: Always `"MESSAGE"` for this type.
84+
* **payload**: Optional message content.
85+
86+
---
87+
88+
### 2. **Database Table Change Payload**
89+
90+
Generated automatically when a transaction modifies a subscribed table. Triggered at **COMMIT** time and may include multiple row operations.
4391

44-
**2. Multiple TABLE modification payload**
4592
```json
4693
{
47-
sender: "UUID",
48-
channel: "tablename",
49-
type: "TABLE",
50-
pk: ["id", "col1"], // array of primary key name(s)
51-
payload: [ // array of operations that affect table name
52-
{
53-
type: "INSERT",
54-
id: 12,
55-
col1: "value1",
56-
col2: 3.14
57-
},
58-
{
59-
type: "DELETE",
60-
pv: [13], // primary key value (s) in the same order as the pk array
61-
},
62-
{
63-
type: "UPDATE",
64-
id: 15, // new value
65-
col1: "newvalue",
66-
col2: 0.0,
67-
// if primary key is updated during this update then add it to:
68-
// UPDATE TABLE SET col1='newvalue', col2=0.0, id = 15 WHERE id=14
69-
pv: [14] // primary key value (s) set prior to this UPDATE operation
70-
}
71-
]
94+
"sender": "UUID",
95+
"channel": "tablename",
96+
"channel_type": "TABLE",
97+
"sqlite_pk_name": ["id", "col1"],
98+
"payload": [
99+
{
100+
"sqlite_type": "INSERT",
101+
"id": 12,
102+
"col1": "value1",
103+
"col2": 3.14
104+
},
105+
{
106+
"sqlite_type": "DELETE",
107+
"sqlite_pk_value": [13]
108+
},
109+
{
110+
"sqlite_type": "UPDATE",
111+
"id": 15,
112+
"col1": "newvalue",
113+
"col2": 0.0,
114+
"sqlite_pk_value": [14]
115+
}
116+
]
72117
}
73118
```
74119

75-
**Details:**
120+
#### Field Descriptions:
76121

77-
* **sender**: is the UUID of the client who sent the NOTIFY event or who initiated the WRITE operation that triggers the notification. It is common for a client that executes **NOTIFY** to be listening on the same notification channel itself. In that case it will get back a notification event, just like all the other listening sessions. Depending on the application logic, this could result in useless work, for example, reading a database table to find the same updates that that session just wrote out. It is possible to avoid such extra work by noticing whether the notifying **UUID** (supplied in the notification event message) is the same as one's **UUID** (available from SDK). When they are the same, the notification event is one's own work bouncing back, and can be ignored. If **UUID** is 0 it means that server sent that payload.
78-
* **channel**: this field represents the channel/table affected.
79-
* **type**: determine the type of operation, it can be: MESSAGE, TABLE, INSERT, UPDATE, or DELETE (more to come).
80-
* **pk/pv**: these fields represent the primary key name(s) and value(s) affected by this table operation.
81-
* **payload**: TODO
122+
* **sender**: UUID of the client initiating the change, or `0` if triggered by the server.
123+
* **channel**: Table name where the change occurred.
124+
* **channel\_type**: `"TABLE"`.
125+
* **sqlite\_pk\_name**: Array of primary key column names for the table.
126+
* **payload**: Array of individual row operations.
82127

83-
**More SQL examples:**
84-
```
128+
* **sqlite\_type**: `"INSERT"`, `"UPDATE"`, or `"DELETE"`.
129+
* **sqlite\_pk\_value**: Previous primary key values (used in `DELETE` or `UPDATE`).
130+
* Other keys represent column values (for `INSERT` and `UPDATE`).
131+
132+
> **Tip:** If a client is subscribed to a channel and also publishes to it, it will receive its own notifications. Use the **sender UUID** to filter out self-generated events if needed.
133+
134+
---
135+
136+
## Example SQL Usage
137+
138+
```sql
85139
> USE DATABASE test.sqlite
86140
OK
87141

88142
> GET SQL foo
89-
CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY AUTOINCREMENT, "col1" TEXT, "col2" TEXT)
143+
CREATE TABLE "foo" (
144+
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
145+
"col1" TEXT,
146+
"col2" TEXT
147+
)
90148

91149
> LISTEN TABLE foo
92150
OK
93151
```
94152

95-
**3. DELETE FROM foo WHERE id=14;**
153+
---
154+
155+
## Example Event Payloads
156+
157+
### DELETE
158+
159+
```sql
160+
DELETE FROM foo WHERE id=14;
161+
```
162+
96163
```json
97164
{
98-
"sender": "b7a92805-ef82-4ad1-8c2f-92da6df6b1d5",
99-
"channel": "foo",
100-
"type": "TABLE",
101-
"pk": ["id"],
102-
"payload": [{
103-
"type": "DELETE",
104-
"pv": [14]
105-
}]
165+
"sender": "b7a92805-ef82-4ad1-8c2f-92da6df6b1d5",
166+
"channel": "foo",
167+
"channel_type": "TABLE",
168+
"sqlite_pk_name": ["id"],
169+
"payload": [{
170+
"sqlite_type": "DELETE",
171+
"sqlite_pk_value": [14]
172+
}]
106173
}
107174
```
108175

109-
**4. INSERT INTO foo(col1, col2) VALUES ('test100', 'test101');**
176+
---
177+
178+
### INSERT
179+
180+
```sql
181+
INSERT INTO foo(col1, col2) VALUES ('test100', 'test101');
182+
```
183+
110184
```json
111185
{
112-
"sender": "b7a92805-ef82-4ad1-8c2f-92da6df6b1d5",
113-
"channel": "foo",
114-
"type": "TABLE",
115-
"pk": ["id"],
116-
"payload": [{
117-
"type": "INSERT",
118-
"id": 15,
119-
"col1": "test100",
120-
"col2": "test101"
121-
}]
186+
"sender": "b7a92805-ef82-4ad1-8c2f-92da6df6b1d5",
187+
"channel": "foo",
188+
"channel_type": "TABLE",
189+
"sqlite_pk_name": ["id"],
190+
"payload": [{
191+
"sqlite_type": "INSERT",
192+
"id": 15,
193+
"col1": "test100",
194+
"col2": "test101"
195+
}]
122196
}
123197
```
124198

125-
**5. UPDATE foo SET id=14,col1='test200' WHERE id=15;**
199+
---
200+
201+
### UPDATE (Primary Key Changed)
202+
203+
```sql
204+
UPDATE foo SET id=14, col1='test200' WHERE id=15;
205+
```
206+
126207
```json
127208
{
128-
"sender": "b7a92805-ef82-4ad1-8c2f-92da6df6b1d5",
129-
"channel": "foo",
130-
"type": "TABLE",
131-
"pk": ["id"],
132-
"payload": [{
133-
"type": "DELETE",
134-
"pv": [15]
135-
}, {
136-
"type": "INSERT",
137-
"id": 14,
138-
"col1": "test200",
139-
"col2": "test101"
140-
}]
209+
"sender": "b7a92805-ef82-4ad1-8c2f-92da6df6b1d5",
210+
"channel": "foo",
211+
"channel_type": "TABLE",
212+
"sqlite_pk_name": ["id"],
213+
"payload": [
214+
{
215+
"sqlite_type": "DELETE",
216+
"sqlite_pk_value": [15]
217+
},
218+
{
219+
"sqlite_type": "INSERT",
220+
"id": 14,
221+
"col1": "test200",
222+
"col2": "test101"
223+
}
224+
]
141225
}
142226
```
143227

228+
---
229+
230+
## Summary
231+
232+
SQLiteCloud's Pub/Sub system enables:
233+
234+
* Real-time data sync across applications.
235+
* Lightweight messaging between distributed components.
236+
* Fine-grained, reliable notifications with minimal overhead.
237+
238+
By leveraging Pub/Sub, developers can build responsive, event-driven applications that scale seamlessly and remain in sync with the database state.
239+
144240
## Client Library Examples
145241

146242
```javascript

0 commit comments

Comments
 (0)