Adds an entry to a stream. Like XADD without trimming. * * - `key`: The key where the stream is (or will be) stored * - `flags`: A bit field of * - `REDISMODULE_STREAM_ADD_AUTOID`: Assign a stream ID automatically, like * `*` in the XADD command. * - `id`: If the `AUTOID` flag is set, this is where the assigned ID is * returned. Can be NULL if `AUTOID` is set, if you don't care to r
| 3322 | * - ERANGE if the elements are too large to be stored. |
| 3323 | */ |
| 3324 | int RM_StreamAdd(RedisModuleKey *key, int flags, RedisModuleStreamID *id, RedisModuleString **argv, long numfields) { |
| 3325 | /* Validate args */ |
| 3326 | if (!key || (numfields != 0 && !argv) || /* invalid key or argv */ |
| 3327 | (flags & ~(REDISMODULE_STREAM_ADD_AUTOID)) || /* invalid flags */ |
| 3328 | (!(flags & REDISMODULE_STREAM_ADD_AUTOID) && !id)) { /* id required */ |
| 3329 | errno = EINVAL; |
| 3330 | return REDISMODULE_ERR; |
| 3331 | } else if (key->value && key->value->type != OBJ_STREAM) { |
| 3332 | errno = ENOTSUP; /* wrong type */ |
| 3333 | return REDISMODULE_ERR; |
| 3334 | } else if (!(key->mode & REDISMODULE_WRITE)) { |
| 3335 | errno = EBADF; /* key not open for writing */ |
| 3336 | return REDISMODULE_ERR; |
| 3337 | } else if (!(flags & REDISMODULE_STREAM_ADD_AUTOID) && |
| 3338 | id->ms == 0 && id->seq == 0) { |
| 3339 | errno = EDOM; /* ID out of range */ |
| 3340 | return REDISMODULE_ERR; |
| 3341 | } |
| 3342 | |
| 3343 | /* Create key if necessery */ |
| 3344 | int created = 0; |
| 3345 | if (key->value == NULL) { |
| 3346 | moduleCreateEmptyKey(key, REDISMODULE_KEYTYPE_STREAM); |
| 3347 | created = 1; |
| 3348 | } |
| 3349 | |
| 3350 | stream *s = key->value->ptr; |
| 3351 | if (s->last_id.ms == UINT64_MAX && s->last_id.seq == UINT64_MAX) { |
| 3352 | /* The stream has reached the last possible ID */ |
| 3353 | errno = EFBIG; |
| 3354 | return REDISMODULE_ERR; |
| 3355 | } |
| 3356 | |
| 3357 | streamID added_id; |
| 3358 | streamID use_id; |
| 3359 | streamID *use_id_ptr = NULL; |
| 3360 | if (!(flags & REDISMODULE_STREAM_ADD_AUTOID)) { |
| 3361 | use_id.ms = id->ms; |
| 3362 | use_id.seq = id->seq; |
| 3363 | use_id_ptr = &use_id; |
| 3364 | } |
| 3365 | if (streamAppendItem(s, argv, numfields, &added_id, use_id_ptr) == C_ERR) { |
| 3366 | /* Either the ID not greater than all existing IDs in the stream, or |
| 3367 | * the elements are too large to be stored. either way, errno is already |
| 3368 | * set by streamAppendItem. */ |
| 3369 | return REDISMODULE_ERR; |
| 3370 | } |
| 3371 | /* Postponed signalKeyAsReady(). Done implicitly by moduleCreateEmptyKey() |
| 3372 | * so not needed if the stream has just been created. */ |
| 3373 | if (!created) key->u.stream.signalready = 1; |
| 3374 | |
| 3375 | if (id != NULL) { |
| 3376 | id->ms = added_id.ms; |
| 3377 | id->seq = added_id.seq; |
| 3378 | } |
| 3379 | |
| 3380 | return REDISMODULE_OK; |
| 3381 | } |
nothing calls this directly
no test coverage detected