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
| 3410 | * - ERANGE if the elements are too large to be stored. |
| 3411 | */ |
| 3412 | int RM_StreamAdd(RedisModuleKey *key, int flags, RedisModuleStreamID *id, RedisModuleString **argv, long numfields) { |
| 3413 | /* Validate args */ |
| 3414 | if (!key || (numfields != 0 && !argv) || /* invalid key or argv */ |
| 3415 | (flags & ~(REDISMODULE_STREAM_ADD_AUTOID)) || /* invalid flags */ |
| 3416 | (!(flags & REDISMODULE_STREAM_ADD_AUTOID) && !id)) { /* id required */ |
| 3417 | errno = EINVAL; |
| 3418 | return REDISMODULE_ERR; |
| 3419 | } else if (key->value && key->value->type != OBJ_STREAM) { |
| 3420 | errno = ENOTSUP; /* wrong type */ |
| 3421 | return REDISMODULE_ERR; |
| 3422 | } else if (!(key->mode & REDISMODULE_WRITE)) { |
| 3423 | errno = EBADF; /* key not open for writing */ |
| 3424 | return REDISMODULE_ERR; |
| 3425 | } else if (!(flags & REDISMODULE_STREAM_ADD_AUTOID) && |
| 3426 | id->ms == 0 && id->seq == 0) { |
| 3427 | errno = EDOM; /* ID out of range */ |
| 3428 | return REDISMODULE_ERR; |
| 3429 | } |
| 3430 | |
| 3431 | /* Create key if necessery */ |
| 3432 | int created = 0; |
| 3433 | if (key->value == NULL) { |
| 3434 | moduleCreateEmptyKey(key, REDISMODULE_KEYTYPE_STREAM); |
| 3435 | created = 1; |
| 3436 | } |
| 3437 | |
| 3438 | stream *s = (stream*)ptrFromObj(key->value); |
| 3439 | if (s->last_id.ms == UINT64_MAX && s->last_id.seq == UINT64_MAX) { |
| 3440 | /* The stream has reached the last possible ID */ |
| 3441 | errno = EFBIG; |
| 3442 | return REDISMODULE_ERR; |
| 3443 | } |
| 3444 | |
| 3445 | streamID added_id; |
| 3446 | streamID use_id; |
| 3447 | streamID *use_id_ptr = NULL; |
| 3448 | if (!(flags & REDISMODULE_STREAM_ADD_AUTOID)) { |
| 3449 | use_id.ms = id->ms; |
| 3450 | use_id.seq = id->seq; |
| 3451 | use_id_ptr = &use_id; |
| 3452 | } |
| 3453 | if (streamAppendItem(s, argv, numfields, &added_id, use_id_ptr) == C_ERR) { |
| 3454 | /* Either the ID not greater than all existing IDs in the stream, or |
| 3455 | * the elements are too large to be stored. either way, errno is already |
| 3456 | * set by streamAppendItem. */ |
| 3457 | return REDISMODULE_ERR; |
| 3458 | } |
| 3459 | /* Postponed signalKeyAsReady(). Done implicitly by moduleCreateEmptyKey() |
| 3460 | * so not needed if the stream has just been created. */ |
| 3461 | if (!created) key->u.stream.signalready = 1; |
| 3462 | |
| 3463 | if (id != NULL) { |
| 3464 | id->ms = added_id.ms; |
| 3465 | id->seq = added_id.seq; |
| 3466 | } |
| 3467 | |
| 3468 | return REDISMODULE_OK; |
| 3469 | } |
nothing calls this directly
no test coverage detected