This project provides Redis utility functions for IBM i, enabling seamless interaction with a Redis server through SQL User-Defined Functions (UDFs). It includes four main functions:
REDIS_GET
: Retrieves a value from Redis using a specified key.REDIS_SET
: Sets a value in Redis using a key-value pair.REDIS_INCR
: Increments the integer value of a key by 1. If the key does not exist, it is set to 0 before performing the operation.REDIS_DEL
: Deletes a key from Redis. Returns 1 if the key was deleted, or 0 if the key did not exist.REDIS_EXPIRE
(New as of March 12, 2025): Sets an expiration time (TTL) in seconds for a Redis key.REDIS_TTL
(New as of March 12, 2025): Retrieves the remaining time-to-live (TTL) of a Redis key in seconds.
Built with a Makefile, the project automates compilation, binding, and deployment of these functions, making it easy to integrate Redis caching or storage into IBM i applications.
- Prerequisites
- Project Structure
- Makefile Targets
- Building the Project
- Cleaning Up
- Usage
- Redis Configuration
- License
- Contributing
- Authors
Before building and using the project, ensure you have the following:
- IBM i Access: Access to an IBM i system with development tools (e.g., ILE C compiler, SQL).
- Redis Server: A Redis server running and accessible from the IBM i system (default:
127.0.0.1:6379
). - GCC for PASE: Required for compiling C modules in PASE, if applicable (install via
yum install gcc
in PASE). - Makefile Support: Ensure the
make
command is available (install viayum install make
in PASE, if needed). - Git: For cloning the repository (optional, but recommended).
The project is organized as follows:
/project-root/
srcfile/
# Source files for C modulesredisget.c
# Source for REDIS_GET functionredisset.c
# Source for REDIS_SET functionredisincr.c
# Source for REDIS_INCR functionredisdel.c
# Source for REDIS_DEL functionredisexp.c
# Source for REDIS_EXPIRE function (added March 12, 2025)redisttl.c
# Source for REDIS_TTL function (added March 12, 2025)redisutils.c
# Shared utility functions
qsrvsrc/
# Binding source filesredisget.bnd
# Binding source for REDIS_GETredisset.bnd
# Binding source for REDIS_SETredisincr.bnd
# Binding source for REDIS_INCRredisdel.bnd
# Binding source for REDIS_DELredisexp.bnd
# Binding source for REDIS_EXPIRE (add this file)redisttl.bnd
# Binding source for REDIS_TTL (add this file)redisutils.bnd
# Binding source for shared utilities
include/
# Header filesredis_utils.h
# Header for shared utilities
Makefile
# Makefile for building the projectREADME.md
# This file
The Makefile provides the following targets to manage the build process:
Target | Description |
---|---|
all |
Builds everything: library, service program, and SQL functions. |
preflight |
Checks if the target library (REDIS400 ) exists and prompts for deletion. |
$(TGT_LIB).lib |
Creates the target library (REDIS400 by default). |
redisile.srvpgm |
Creates the service program from compiled modules. |
redis_get.func |
Creates or replaces the REDIS_GET SQL function. |
redis_set.func |
Creates or replaces the REDIS_SET SQL function. |
redis_incr.func |
Creates or replaces the REDIS_INCR SQL function. |
redis_del.func |
Creates or replaces the REDIS_DEL SQL function. |
redis_exp.func |
Creates or replaces the REDIS_EXPIRE SQL function (added March 12, 2025). |
redis_ttl.func |
Creates or replaces the REDIS_TTL SQL function (added March 12, 2025). |
clean |
Deletes the target library and all associated objects. |
Follow these steps to build and deploy the Redis utility functions on IBM i:
Ensure all prerequisites are installed and configured as described above.
-
Clone the Repository:
git clone https://github.com/krakadin/redis400.git cd redis400
-
Run the Makefile:
gmake
When you run gmake
, the following steps are executed:
-
Create the Target Library (
REDIS400
):- The target library
REDIS400
is created to store all the compiled objects.
- The target library
-
Compile the C Modules into ILE Modules:
- The C source files (redisget.c, redisset.c, redisincr.c, redisdel.c, redisexp.c, redisttl.c, and redisutils.c) are compiled into ILE modules:
REDISGET
REDISSET
REDISINCR
REDISDEL
REDISEXP
REDISTTL
REDISUTILS
- The C source files (redisget.c, redisset.c, redisincr.c, redisdel.c, redisexp.c, redisttl.c, and redisutils.c) are compiled into ILE modules:
-
Create the Service Program (
redisile.srvpgm
):- The compiled modules are bound together to create the service program
REDISILE
.
- The compiled modules are bound together to create the service program
-
Create the SQL Functions:
- The SQL functions
REDIS_GET
,REDIS_SET
,REDIS_INCR
,REDIS_DEL
,REDIS_EXPIRE
, andREDIS_TTL
are created or replaced in the target library.
- The SQL functions
Note: If the execution failes due errors in generate_config.sh
, you may need to modify git settings core.autocrlf
git config --global core.autocrlf input
After the build process completes, verify the following objects in the target library (REDIS400
):
REDISGET
REDISSET
REDISINCR
REDISDEL
REDISEXP
REDISTTL
REDISUTILS
REDISILE
REDIS_GET
REDIS_SET
REDIS_INCR
REDIS_DEL
REDIS_EXPIRE
REDIS_TTL
-
Check Modules:
DSPOBJD OBJ(REDIS400/REDISGET) OBJTYPE(*MODULE) DSPOBJD OBJ(REDIS400/REDISSET) OBJTYPE(*MODULE) DSPOBJD OBJ(REDIS400/REDISINCR) OBJTYPE(*MODULE) DSPOBJD OBJ(REDIS400/REDISDEL) OBJTYPE(*MODULE) DSPOBJD OBJ(REDIS400/REDISEXP) OBJTYPE(*MODULE) DSPOBJD OBJ(REDIS400/REDISTTL) OBJTYPE(*MODULE) DSPOBJD OBJ(REDIS400/REDISUTILS) OBJTYPE(\*MODULE)
-
Check Service Program:
DSPOBJD OBJ(REDIS400/REDISILE) OBJTYPE(\*SRVPGM)
-
Check SQL Functions:
SELECT FROM QSYS2.SYSFUNCS WHERE SPECIFIC_NAME = 'REDIS_GET'); SELECT FROM QSYS2.SYSFUNCS WHERE SPECIFIC_NAME = 'REDIS_SET'); SELECT FROM QSYS2.SYSFUNCS WHERE SPECIFIC_NAME = 'REDIS_INCR'); SELECT FROM QSYS2.SYSFUNCS WHERE SPECIFIC_NAME = 'REDIS_DEL'); SELECT * FROM QSYS2.SYSFUNCS WHERE SPECIFIC_NAME = 'REDIS_EXPIRE'; SELECT * FROM QSYS2.SYSFUNCS WHERE SPECIFIC_NAME = 'REDIS_TTL';
To clean up the project and remove all generated objects, run:
make clean
This deletes the REDIS400 library and all its contents.
Once built, use the SQL functions in your IBM i SQL queries to interact with Redis.
- Retrieve a Value (REDIS_GET): Use this function to get a value associated with a key from Redis.
- Set a Value (REDIS_SET): Use this function to set a key-value pair in Redis.
- Increment a Value (REDIS_INCR): Use this function to increment the integer value of a key by 1.
- Delete a Key (REDIS_DEL): Remove a key from Redis.
- Set Expiration (REDIS_EXPIRE): Assign a time-to-live (TTL) to a key.
- Check TTL (REDIS_TTL): Retrieve the remaining time-to-live of a key.
SELECT REDIS_GET('API_KEY') AS value FROM SYSIBM.SYSDUMMY1;
VALUES REDIS_SET('API_KEY', 'my_value');
SET ORDER_NO = REDIS_INCR('ORDER#');
VALUES REDIS_DEL('API_KEY');
SELECT REDIS_EXPIRE('API_KEY', 300) FROM SYSIBM.SYSDUMMY1;
- Sets API_KEY to expire in 300 seconds (5 minutes). Returns 1 if successful, 0 if the key doesn’t exist.
SELECT REDIS_TTL('API_KEY') FROM SYSIBM.SYSDUMMY1;
- Returns the remaining TTL in seconds (e.g., 298), -1 if no expiration, or -2 if the key doesn’t exist.
Ensure the Redis server is running and accessible at 127.0.0.1:6379
(configurable in .env
).
Handle errors via SQLSTATE (e.g., 38908
for payload extraction failures, 38904
for timeouts).
This section details how to configure and optimize your Redis server for use with the IBM i UDFs.
- Installation: Install Redis on IBM i PASE or a remote server using yum install redis in PASE, or configure a remote Redis instance.
- Configuration:
- Edit
/QOpenSys/etc/redis.conf
(if on PASE) or the Redis configuration file to bind to127.0.0.1
and listen on port6379
. - Ensure
requirepass
is set (if password protection is needed) and updatesetRedisValue
to handle authentication (e.g.,AUTH
command).
- Edit
- Starting Redis:
redis-server /QOpenSys/etc/redis.conf > /dev/null 2>&1 &
- Testing Connectivity:
redis-cli -h 127.0.0.1 -p 6379 PING
Expected output: PONG
.
- If
REDIS_SET
orREDIS_GET
fails with timeouts, verify network connectivity and increase the socket timeout inconnect_to_redis
(e.g.,timeout.tv_sec = 5
). For-ERR unknown command
, ensure the RESP format is correct (e.g.,\*3\r\n$3\r\nSET\r\n...
).
This project is licensed under the MIT License. See the LICENSE file for details.
Contributions are welcome! To contribute to this project:
-
Fork the repository on GitHub.
-
Create a new branch for your feature or bug fix:
git checkout -b feature/your-feature
-
Make your changes, commit them, and push to your fork:
git add . git commit -m "Add your feature or fix" git push origin feature/your-feature
-
Submit a pull request to the main repository. Please follow the coding standards in the C source files and test your changes on IBM i.
- Ernest Rozloznik
- Roadmap: Future enhancements may include additional Redis commands (e.g.,
APPEND
,AUTH
,SCAN
), Python integration, and improved error handling. - Acknowledgments: Thanks to the IBM i and Redis communities for their tools and support.