Skip to content

Commit 8c5e4b9

Browse files
Lorenzo ManganiLorenzo Mangani
Lorenzo Mangani
authored and
Lorenzo Mangani
committed
local
1 parent ae1bb2b commit 8c5e4b9

File tree

1 file changed

+94
-54
lines changed

1 file changed

+94
-54
lines changed

docs/README.md

Lines changed: 94 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,138 @@
1-
# DuckDB Redis Extension
2-
This extension provides Redis client functionality for DuckDB, allowing you to interact with a Redis server directly from SQL queries. The extension uses Boost.Asio for network communication and implements basic Redis protocol commands.
1+
<img src="https://github.com/user-attachments/assets/46a5c546-7e9b-42c7-87f4-bc8defe674e0" width=250 />
2+
3+
# DuckDB Redis Client Extension
4+
This extension provides Redis client functionality for DuckDB, allowing you to interact with a Redis server directly from SQL queries.
5+
6+
> Experimental: USE AT YOUR OWN RISK!
37
48
## Features
59
Currently supported Redis operations:
6-
- `redis_get(key, host, port, password)`: Retrieves a value from Redis for a given key
7-
- `redis_set(key, value, host, port, password)`: Sets a value in Redis for a given key
8-
9-
Features:
10-
- Connection pooling for improved performance
11-
- Redis authentication support
12-
- Thread-safe operations
13-
- Detailed error handling
10+
- String operations: `GET`, `SET`
11+
- Hash operations: `HGET`, `HSET`
12+
- List operations: `LPUSH`, `LRANGE`
13+
- Batch operations: `MGET`, `SCAN`
1414

1515
## Installation
1616
```sql
17-
INSTALL 'redis' FROM community;
18-
LOAD 'redis';
17+
INSTALL redis FROM community;
18+
LOAD redis;
1919
```
2020

21-
## Usage Examples
22-
### Connecting with Authentication
21+
## Usage
22+
### Setting up Redis Connection
23+
First, create a secret to store your Redis connection details:
2324
```sql
24-
-- Set a value with authentication
25-
SELECT redis_set('user:1', 'John Doe', 'localhost', '6379', 'mypassword') as result;
26-
27-
-- Get a value with authentication
28-
SELECT redis_get('user:1', 'localhost', '6379', 'mypassword') as user_name;
29-
30-
-- For non-authenticated Redis servers, pass an empty string as password
31-
SELECT redis_get('user:1', 'localhost', '6379', '') as user_name;
25+
-- Create a Redis connection secret
26+
CALL redis_create_secret('my_redis', {
27+
'host': 'localhost',
28+
'port': '6379',
29+
'password': 'optional_password'
30+
});
31+
32+
-- For cloud Redis services (e.g., Redis Labs)
33+
CALL redis_create_secret('redis_cloud', {
34+
'host': 'redis-xxxxx.cloud.redislabs.com',
35+
'port': '16379',
36+
'password': 'your_password'
37+
});
3238
```
3339

34-
### Setting Values in Redis
40+
### String Operations
3541
```sql
36-
-- Set a single value
37-
SELECT redis_set('user:1', 'John Doe', 'localhost', '6379') as result;
42+
-- Set a value
43+
SELECT redis_set('user:1', 'John Doe', 'my_redis') as result;
44+
45+
-- Get a value
46+
SELECT redis_get('user:1', 'my_redis') as user_name;
3847

3948
-- Set multiple values in a query
40-
INSERT INTO users (id, name, age)
41-
SELECT redis_set(
49+
INSERT INTO users (id, name)
50+
SELECT id, redis_set(
4251
'user:' || id::VARCHAR,
4352
name,
44-
'localhost',
45-
'6379'
53+
'my_redis'
4654
)
4755
FROM new_users;
4856
```
4957

50-
### Getting Values from Redis
58+
### Hash Operations
59+
```sql
60+
-- Set hash fields
61+
SELECT redis_hset('user:1', 'email', '[email protected]', 'my_redis');
62+
SELECT redis_hset('user:1', 'age', '30', 'my_redis');
63+
64+
-- Get hash field
65+
SELECT redis_hget('user:1', 'email', 'my_redis') as email;
66+
67+
-- Store user profile as hash
68+
WITH profile(id, field, value) AS (
69+
VALUES
70+
(1, 'name', 'John Doe'),
71+
(1, 'email', '[email protected]'),
72+
(1, 'age', '30')
73+
)
74+
SELECT redis_hset(
75+
'user:' || id::VARCHAR,
76+
field,
77+
value,
78+
'my_redis'
79+
)
80+
FROM profile;
81+
```
82+
83+
### List Operations
5184
```sql
52-
-- Get a single value
53-
SELECT redis_get('user:1', 'localhost', '6379') as user_name;
54-
55-
-- Get multiple values
56-
SELECT
57-
id,
58-
redis_get('user:' || id::VARCHAR, 'localhost', '6379') as user_data
59-
FROM user_ids;
85+
-- Push items to list
86+
SELECT redis_lpush('mylist', 'first_item', 'my_redis');
87+
SELECT redis_lpush('mylist', 'second_item', 'my_redis');
88+
89+
-- Get range from list (returns comma-separated values)
90+
-- Get all items (0 to -1 means start to end)
91+
SELECT redis_lrange('mylist', 0, -1, 'my_redis') as items;
92+
93+
-- Get first 5 items
94+
SELECT redis_lrange('mylist', 0, 4, 'my_redis') as items;
95+
96+
-- Push multiple items
97+
WITH items(value) AS (
98+
VALUES ('item1'), ('item2'), ('item3')
99+
)
100+
SELECT redis_lpush('mylist', value, 'my_redis')
101+
FROM items;
60102
```
61103

62104
### Batch Operations
63105
```sql
64106
-- Get multiple keys at once
65-
SELECT redis_mget('key1,key2,key3', 'localhost', '6379', '') as values;
107+
SELECT redis_mget('key1,key2,key3', 'my_redis') as values;
66108

67109
-- Scan keys matching a pattern
68-
SELECT redis_scan('0', 'user:*', 10, 'localhost', '6379', '') as result;
110+
SELECT redis_scan('0', 'user:*', 10, 'my_redis') as result;
69111
-- Returns: "cursor:key1,key2,key3" where cursor is the next position for scanning
70112
-- Use the returned cursor for the next scan until cursor is 0
71113

72114
-- Scan all keys matching a pattern
73115
WITH RECURSIVE scan(cursor, keys) AS (
74116
-- Initial scan
75-
SELECT split_part(redis_scan('0', 'user:*', 10, 'localhost', '6379', ''), ':', 1),
76-
split_part(redis_scan('0', 'user:*', 10, 'localhost', '6379', ''), ':', 2)
117+
SELECT split_part(redis_scan('0', 'user:*', 10, 'my_redis'), ':', 1),
118+
split_part(redis_scan('0', 'user:*', 10, 'my_redis'), ':', 2)
77119
UNION ALL
78120
-- Continue scanning until cursor is 0
79-
SELECT split_part(redis_scan(cursor, 'user:*', 10, 'localhost', '6379', ''), ':', 1),
80-
split_part(redis_scan(cursor, 'user:*', 10, 'localhost', '6379', ''), ':', 2)
121+
SELECT split_part(redis_scan(cursor, 'user:*', 10, 'my_redis'), ':', 1),
122+
split_part(redis_scan(cursor, 'user:*', 10, 'my_redis'), ':', 2)
81123
FROM scan
82124
WHERE cursor != '0'
83125
)
84126
SELECT keys FROM scan;
85127
```
86128

129+
## Error Handling
130+
The extension functions will throw exceptions with descriptive error messages when:
131+
- Redis secret is not found or invalid
132+
- Unable to connect to Redis server
133+
- Network communication errors occur
134+
- Invalid Redis protocol responses are received
135+
87136
## Building from Source
88137
Follow the standard DuckDB extension build process:
89138

@@ -98,18 +147,9 @@ make
98147
## Dependencies
99148
- Boost.Asio (header-only, installed via vcpkg)
100149

101-
## Error Handling
102-
The extension functions will throw exceptions with descriptive error messages when:
103-
- Unable to connect to Redis server
104-
- Network communication errors occur
105-
- Invalid Redis protocol responses are received
106-
107150
## Future Enhancements
108151
Planned features include:
109-
- Support for Redis authentication
110-
- Connection pooling for better performance
111-
- Additional Redis commands (HGET, HSET, LPUSH, etc.)
112-
- Table functions for scanning Redis keys
152+
- Additional Redis commands (SADD, SMEMBERS, etc.)
113153
- Batch operations using Redis pipelines
114154
- Connection timeout handling
115155

0 commit comments

Comments
 (0)